skill_attributes.c-Dateireferenz

#include <living/skill_attributes.h>
#include <player/life.h>
#include <thing/properties.h>
#include <defines.h>
Include-Abhängigkeitsdiagramm für skill_attributes.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define NEED_PROTOTYPES
#define ZDEBUG(x)

Funktionen

protected void create ()
mapping _set_skill_attr (mapping sa)
mapping _query_skill_attr ()
private void UpdateSACache (string *attrs)
private int InternalModifySkillAttribute (object caster, string atrname, mixed value, int duration)
public int ModifySkillAttribute (string atrname, mixed value, int duration)
public int RemoveSkillAttributeModifier (object caster, string attrname)
public int QuerySkillAttribute (string atrname)
public varargs mapping QuerySkillAttributeModifier (object caster, string *attrnames)
public varargs int ModifySkillAttributeOld (object caster, string atrname, int value, int duration, mixed fun)

Variablen

inherit std util executer
private nosave mapping skillattrs

Makro-Dokumentation

#define NEED_PROTOTYPES

Definiert in Zeile 14 der Datei skill_attributes.c.

#define ZDEBUG ( x   ) 

Definiert in Zeile 24 der Datei skill_attributes.c.


Dokumentation der Funktionen

mapping _query_skill_attr (  ) 

Definiert in Zeile 49 der Datei skill_attributes.c.

Benutzt skillattrs.

00049                             {
00050   return deep_copy(skillattrs);
00051 
00052 //TODO: Evtl. ext. Setzen von P_SKILL_ATTRIBUTE_OFFSETS mitloggen?
00053 }

mapping _set_skill_attr ( mapping  sa  ) 

Definiert in Zeile 45 der Datei skill_attributes.c.

Benutzt skillattrs.

00045                                     {
00046   return deep_copy(skillattrs);
00047 }

protected void create (  ) 

Definiert in Zeile 40 der Datei skill_attributes.c.

Benutzt F_MODE_AS, P_SKILL_ATTRIBUTES, SECURED und Set().

00040                         {
00041   Set(P_SKILL_ATTRIBUTES, SECURED, F_MODE_AS);
00042 }

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

private int InternalModifySkillAttribute ( object  caster,
string  atrname,
mixed  value,
int  duration 
)

Definiert in Zeile 112 der Datei skill_attributes.c.

Benutzt m_delete(), ME, SA_MOD_INVALID_ATTR, SA_MOD_INVALID_OBJECT, SA_MOD_INVALID_VALUE, SA_MOD_OK, SA_MOD_TOO_BIG, SA_MOD_TOO_SMALL, SA_TOO_MANY_MODS, SAM_CACHE, SAM_COUNT, SAM_DYNAMIC, SAM_MAX_MODS, SAM_STATIC, SASTATD, skillattrs, strftime(), UpdateSACache(), VALID_SKILL_ATTRIBUTES, ZDEBUG und zeit.

Wird benutzt von ModifySkillAttribute() und ModifySkillAttributeOld().

00113                                                            {
00114   int zeit = utime()[1];
00115   int ticks = get_eval_cost();
00116 
00117   // nur existierende SAs...
00118   if (!stringp(atrname)
00119       || member(VALID_SKILL_ATTRIBUTES, atrname) == -1)
00120     return SA_MOD_INVALID_ATTR;
00121 
00122   if (!objectp(caster)) return SA_MOD_INVALID_OBJECT;
00123 
00124   if (!mappingp(skillattrs)) skillattrs=m_allocate(1,3);
00125   
00126   if (!member(skillattrs, atrname)) {
00127     skillattrs[atrname,SAM_CACHE] = ({0, 0, 0});
00128     // die meisten Mods sind statisch, daher auf Verdacht hier fuer einen
00129     // Eintrag Platz reservieren, aber nicht fuer den dyn. Teil.
00130     skillattrs[atrname,SAM_STATIC] = m_allocate(1,2);
00131     skillattrs[atrname,SAM_DYNAMIC] = m_allocate(0,2);
00132   }
00133   // pruefen, ob Maximalzahl an Eintraegen drin ist
00134   else if (skillattrs[atrname,SAM_CACHE][SAM_COUNT] >= SAM_MAX_MODS) {
00135     // letzte Chance: destructete Objekte drin?
00136     skillattrs[atrname,SAM_CACHE][SAM_COUNT] = 
00137       sizeof(skillattrs[atrname,SAM_STATIC])
00138     +sizeof(skillattrs[atrname,SAM_DYNAMIC]);
00139     // es kann sein, dass noch abgelaufene Objekte drinstehen,
00140     // aber die Pruefung ist mir gerade zu teuer. TODO
00141     // nochmal gucken (rest vom cache wird ggf. unten geprueft.)
00142     if (skillattrs[atrname,SAM_CACHE][SAM_COUNT] >= SAM_MAX_MODS)
00143       return SA_TOO_MANY_MODS; // dann nicht.
00144   }
00145 
00146   // Dauer darf nur ein int sein.
00147   if (!intp(duration))
00148     raise_error(sprintf("Wrong argument 3 to ModifySkillAttribute: "
00149     "expected 'int', got %.10O\n", duration));
00150   // Zeitstempel ermitteln
00151   duration += time();
00152 
00153   // statischer oder dyn. Modifier?
00154   if (intp(value)) {
00155     // Mod darf nicht zu gross oder zu klein sein. TODO: Grenzen?
00156     if (value < -1000)
00157       return SA_MOD_TOO_SMALL;
00158     else if (value > 1000)
00159       return SA_MOD_TOO_BIG;
00160     else if (!value)
00161       return SA_MOD_INVALID_VALUE; 
00162     // jedes Objekt darf nur einen mod haben. Wenn dieses schon einen dyn.
00163     // hat, muss der geloescht werden (stat. werden ja eh ersetzt).
00164     if (member(skillattrs[atrname,SAM_DYNAMIC], caster))
00165       efun::m_delete(skillattrs[atrname,SAM_DYNAMIC], caster);
00166     // sonst eintragen
00167     skillattrs[atrname, SAM_STATIC] += ([caster: value; duration]);
00168   }
00169   else if (closurep(value)) {
00170     // nur ein Mod pro Objekt, s.o.
00171     if (member(skillattrs[atrname,SAM_STATIC], caster))
00172       efun::m_delete(skillattrs[atrname,SAM_STATIC], caster);
00173     // direkt ohne weitere Pruefung eintragen
00174     skillattrs[atrname, SAM_DYNAMIC] += ([caster: value; duration]);
00175   }
00176   else
00177     raise_error(sprintf("Wrong argument 2 to ModifySkillAttribute(): "
00178     "expected 'int' or 'closure', got %.10O\n",value));
00179 
00180 #ifdef SASETLOG
00181   if (query_once_interactive(this_object()))
00182     SASETLOG(sprintf("%s: %O, %s, %O, %O\n", 
00183         strftime("%y%m%d-%H%M%S"), this_object(), atrname, caster, value));
00184 #endif
00185 #ifdef SASTATD
00186   object daemon;
00187   if (query_once_interactive(ME)
00188       && objectp(daemon=find_object(SASTATD)))
00189     daemon->LogModifier(caster, atrname, value, duration);
00190 #endif
00191   // noch den Cache fuer dieses SA neu berechnen
00192   // TODO: Cache nur invalidieren, damit er erst bei der naechsten Abfrage
00193   // aktualisiert wird. Spart Zeit, wenn bis dahin mehrere Mods
00194   // entfernt/addiert werden. Dafuer ist die gecache Anzahl an Mods
00195   // inkonsistent.
00196   UpdateSACache( ({atrname}) );
00197 
00198   ZDEBUG(sprintf("MSA: %O, Zeit: %d, Ticks: %d\n",
00199                 this_object(),
00200                 utime()[1]-zeit, ticks-get_eval_cost()));
00201 
00202   return SA_MOD_OK;
00203 }

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

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

public int ModifySkillAttribute ( string  atrname,
mixed  value,
int  duration 
)

Definiert in Zeile 205 der Datei skill_attributes.c.

Benutzt InternalModifySkillAttribute() und ME.

00206                                                   {
00207   return InternalModifySkillAttribute(
00208       (extern_call()?previous_object():ME), atrname, value, duration);
00209 }

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

public varargs int ModifySkillAttributeOld ( object  caster,
string  atrname,
int  value,
int  duration,
mixed  fun 
)

Definiert in Zeile 358 der Datei skill_attributes.c.

Benutzt InternalModifySkillAttribute() und ME.

00359                                                               {
00360   int res;
00361   // Caller ermitteln
00362   if (extern_call()) caster=previous_object();
00363   else caster=ME;
00364 
00365   // Closures koennen via ModifySkillAttributeOld() nicht mehr gesetzt werden,
00366   // da deren Rueckgabewert nicht sinnvoll umgerechnet werden koennen. (Man
00367   // weiss nicht, ob es eine neue oder alte Closure ist.)
00368   if (pointerp(fun) || closurep(fun))
00369       raise_error(sprintf("Closures for SA modifiers can't be set by "
00370       "ModifySkillAttributeOld()! Use ModifySkillAttribute()!\n"));
00371   
00372   res = InternalModifySkillAttribute(caster, atrname, value-100, duration);
00373   // die alte funktion hatte nur 0 fuer ungueltigen Wert und < 0 fuer zu
00374   // kleines Level als Rueckgabewert. Zu kleines Level gibt nicht mehr, also
00375   // bleibt nur 0 als Sammel-Fehlercode uebrig. *seufz*
00376   if (res < 0) return 0;
00377   return res;
00378 }

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

public int QuerySkillAttribute ( string  atrname  ) 

Definiert in Zeile 235 der Datei skill_attributes.c.

Benutzt cl, death_suffering(), m_delete(), ME, ob(), P_SKILL_ATTRIBUTE_OFFSETS, Query(), SA_QUALITY, SAM_CACHE, SAM_CACHE_TIMEOUT, SAM_COUNT, SAM_DYNAMIC, SAM_STATIC, SAM_SUM, skillattrs und UpdateSACache().

Wird benutzt von heart_beat(), LongRangeSkill(), StdSkill_Bihand(), StdSkill_Fight_hands() und StdSkill_Fight_sword().

00236 {
00237   mixed offsets, attr;
00238   int modsumme, qual, ret, cval;
00239 
00240   if (!stringp(atrname)) // VALID_SKILL_ATTRIBUTES beruecksichtigen?
00241     return 100;
00242 
00243   // wenn nicht SA_QUALITY gefragt ist, erstmal jenes ermitteln, weil es den
00244   // ersten Modifier auf alle anderen SAs darstellt. Sonst den Startwert fuer
00245   // SA_QUALITY (100) modifiziert durch evtl. Todesfolgen ermitteln.
00246   if ( atrname != SA_QUALITY )
00247     qual = QuerySkillAttribute(SA_QUALITY);
00248   else
00249     // bei SA_QUALITY gehen die Todesfolgen ein
00250     qual = to_int(100 * pow(0.9, death_suffering()/10.0));
00251 
00252   // Die Offsets sind sozusagen der Basiswert der SAs. Als erstes verwursten,
00253   // sofern vorhanden, nen int drinsteht und der offset != 0 ist.
00254   if ( mappingp(offsets = Query(P_SKILL_ATTRIBUTE_OFFSETS))
00255        && intp(attr=offsets[atrname]) 
00256        && attr)
00257     ret = attr;
00258   else
00259     ret = 100;
00260 
00261   // wenn keine Mods gesetzt sind, wars das jetzt. ;-)
00262   if ( !mappingp(skillattrs)
00263        || !member(skillattrs, atrname) )
00264     return (ret*qual)/100;
00265 
00266   // wenn Cache der stat. Mods abgelaufen oder offenbar Objekte zerstoert
00267   // wurden, muss der Cache neu berechnet werden.
00268   if ( skillattrs[atrname,SAM_CACHE][SAM_CACHE_TIMEOUT] < time()
00269       || sizeof(skillattrs[atrname,SAM_STATIC])
00270          +sizeof(skillattrs[atrname,SAM_DYNAMIC]) !=
00271            skillattrs[atrname,SAM_CACHE][SAM_COUNT] )
00272   {
00273     UpdateSACache( ({atrname}) );
00274     // UpdateSACache() loescht uU das SA-Mapping oder Eintraege daraus.
00275     if ( !mappingp(skillattrs)
00276          || !member(skillattrs, atrname) )
00277     return (ret*qual)/100;
00278   }
00279   // Summe der statischen Mods.
00280   modsumme = skillattrs[atrname,SAM_CACHE][SAM_SUM];
00281 
00282   // TODO! Evtl. andere Daten als ME an die Funktion uebergeben
00283   // TODO! bereits nach Addition des Funktionsrueckgabewertes pruefen, ob der
00284   //       Wertebereich des SA-Modifiers ueberschritten ist, oder freien
00285   //       Wertebereich erlauben und erst am Ende deckeln (aktuelle Variante)
00286   // Dynamische Modifier auswerten
00287   foreach( object ob, closure cl, int duration:
00288            skillattrs[atrname,SAM_DYNAMIC] )
00289   {
00290     if ( duration > time()               // Noch nicht abgelaufen und
00291          && intp(cval=funcall(cl, ME)) ) // Funktion liefert int zurueck
00292       modsumme += cval;
00293     else {
00294       efun::m_delete(skillattrs[atrname,SAM_DYNAMIC], ob);
00295       skillattrs[atrname,SAM_CACHE][SAM_COUNT]--;
00296     }
00297   }
00298   ret = ((ret+modsumme)*qual)/100;
00299   if ( ret < 10 )
00300     ret = 10;
00301   else if ( ret > 1000 )
00302     ret = 1000;
00303 
00304   return ret;
00305 }

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

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

public varargs mapping QuerySkillAttributeModifier ( object  caster,
string *  attrnames 
)

Definiert in Zeile 307 der Datei skill_attributes.c.

Benutzt c, SAM_DURATION, SAM_DYNAMIC, SAM_STATIC, SAM_VALUE, skillattrs und UpdateSACache().

00308                                               {
00309   
00310   // auf abgelaufene Modifikatoren pruefen
00311   if (!pointerp(attrnames))
00312     UpdateSACache( ({}) );
00313   else
00314     UpdateSACache(attrnames);
00315 
00316   if (!mappingp(skillattrs))
00317     return ([]);
00318   if (!pointerp(attrnames) || !sizeof(attrnames))
00319     attrnames = m_indices(skillattrs); // alle durchsuchen
00320   else // schnittmenge der gew. und vorhandenen bilden
00321     attrnames = m_indices(skillattrs) & attrnames;
00322   
00323   mapping res=m_allocate(sizeof(attrnames), 1);
00324 
00325   foreach(string atr: attrnames) {
00326     res[atr] = m_allocate(5, 2); // mal fuer 5 Werte Platz reservieren
00327     if (!objectp(caster)) {
00328       // wenn kein bestimmter caster angefragt ist, alle mods liefern
00329       foreach(object c, int value, int dur: skillattrs[atr, SAM_STATIC]) {
00330                 res[atr] += ([c: value; dur]);
00331       }
00332       foreach(object c, closure value, int dur: skillattrs[atr, SAM_DYNAMIC]) {
00333                 res[atr] += ([c: value; dur]);
00334       }
00335     }
00336     else {
00337       // sonst nur den Mod von caster
00338       if (member(skillattrs[atr, SAM_STATIC], caster)) {
00339                 res[atr] += ([caster: 
00340                                                  skillattrs[atr, SAM_STATIC][caster, SAM_VALUE];
00341                                  skillattrs[atr, SAM_STATIC][caster, SAM_DURATION]
00342                                     ]);
00343       }
00344       else if (member(skillattrs[atr, SAM_DYNAMIC], caster)) {
00345                 res[atr] += ([caster:
00346                                                  skillattrs[atr, SAM_DYNAMIC][caster, SAM_VALUE];
00347                                  skillattrs[atr, SAM_DYNAMIC][caster, SAM_DURATION]
00348                                     ]);
00349       }
00350     }
00351   }
00352   return res;
00353 }

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

public int RemoveSkillAttributeModifier ( object  caster,
string  attrname 
)

Definiert in Zeile 211 der Datei skill_attributes.c.

Benutzt m_delete(), SA_MOD_NOT_FOUND, SA_MOD_REMOVED, SAM_DYNAMIC, SAM_STATIC, skillattrs und UpdateSACache().

00211                                                                         {
00212   if (!stringp(attrname) || !mappingp(skillattrs) || !objectp(caster)
00213       || !member(skillattrs, attrname))
00214     return SA_MOD_NOT_FOUND;
00215   // TODO: Berechtigung pruefen. ;-)
00216 
00217   if (member(skillattrs[attrname, SAM_STATIC], caster)) {
00218     efun::m_delete(skillattrs[attrname, SAM_STATIC], caster);
00219   }
00220   else if (member(skillattrs[attrname, SAM_DYNAMIC], caster)) {
00221     efun::m_delete(skillattrs[attrname, SAM_DYNAMIC], caster);
00222   }
00223   else
00224     return SA_MOD_NOT_FOUND;
00225   
00226   // TODO: Cache nur invalidieren, damit er erst bei der naechsten Abfrage
00227   // aktualisiert wird. Spart Zeit, wenn bis dahin mehrere Mods
00228   // entfernt/addiert werden. Dafuer ist die gecache Anzahl an Mods
00229   // inkonsistent.
00230   UpdateSACache( ({attrname}) );
00231 
00232   return SA_MOD_REMOVED;
00233 }

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

private void UpdateSACache ( string *  attrs  ) 

Definiert in Zeile 55 der Datei skill_attributes.c.

Benutzt m_delete(), ob(), SAM_CACHE, SAM_CACHE_TIMEOUT, SAM_COUNT, SAM_DYNAMIC, SAM_STATIC, SAM_SUM, skillattrs, stat(), sum und ZDEBUG.

Wird benutzt von InternalModifySkillAttribute(), QuerySkillAttribute(), QuerySkillAttributeModifier() und RemoveSkillAttributeModifier().

00055                                           {
00056 #ifdef __DEBUG__
00057     if (getuid(this_object()) == "zesstra")
00058     ZDEBUG(sprintf("%O\n",skillattrs));
00059 #endif
00060   if (!mappingp(skillattrs)) return;
00061   if (!pointerp(attrs) || sizeof(attrs))
00062     attrs = m_indices(skillattrs); // alle
00063   // sonst schnittmenge aus existierenden und den uebergebenen.
00064   attrs = m_indices(skillattrs) & attrs;
00065 
00066   // und jetzt ueber alle gewuenschten SAs drueber
00067   foreach(string attr : attrs) {
00068     int *cache = skillattrs[attr, SAM_CACHE];
00069     mapping stat = skillattrs[attr, SAM_STATIC];
00070     mapping dyn = skillattrs[attr, SAM_DYNAMIC];
00071     int sum = 0;
00072     int timeout = __INT_MAX__;
00073  
00074     // ueber stat. Mods iterieren und Aufsummieren, kleinsten Timeout
00075     // ermitteln.
00076     foreach(object ob, int value, int duration: stat) {
00077       // gueltige Mods aufaddieren, abgelaufene rauswerfen
00078       if (duration >= time()) {
00079         sum += value;
00080         if (duration < timeout)
00081           timeout = duration;
00082       }
00083       else
00084         efun::m_delete(stat, ob); // ja, geht im foreach ;-)
00085     }
00086     // Ablaufzeiten der dyn. Mods pruefen, waere hier zwar nicht unbedingt
00087     // noetig sondern koennte man ausschliesslich im QuerySkillAttribute()
00088     // machen, aber dann waere die Ermittlung der Summe der Mods schwieriger.
00089     foreach(object ob, closure value, int duration: dyn) {
00090       if (duration < time())
00091         efun::m_delete(dyn, ob); // ungueltig, weg damit.
00092     }
00093     // gesamtzahl Mods?
00094     cache[SAM_COUNT] = sizeof(stat) + sizeof(dyn);
00095     if (!cache[SAM_COUNT]) {
00096       // keine mods da, Submapping fuer dieses SA komplett loeschen.
00097       efun::m_delete(skillattrs, attr);
00098       continue;
00099     }
00100     // sonst die anderen Cache-Werte setzen.
00101     cache[SAM_SUM] = sum;
00102     cache[SAM_CACHE_TIMEOUT] = timeout;
00103   }
00104   // wenn alle Mods geloescht wurden.
00105   if (!sizeof(skillattrs)) skillattrs=0;
00106 #ifdef __DEBUG__
00107   if (getuid(this_object()) == "zesstra")
00108     ZDEBUG(sprintf("%O\n",skillattrs));
00109 #endif
00110 }

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

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


Variablen-Dokumentation

inherit std util executer

Definiert in Zeile 12 der Datei skill_attributes.c.

private nosave mapping skillattrs
Erzeugt am Thu Jun 3 14:42:34 2010 für MorgenGrauen Mudlib von  doxygen 1.6.3