#include <living/skill_attributes.h>#include <player/life.h>#include <thing/properties.h>#include <defines.h>
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 |
| #define NEED_PROTOTYPES |
Definiert in Zeile 14 der Datei skill_attributes.c.
| #define ZDEBUG | ( | x | ) |
Definiert in Zeile 24 der Datei skill_attributes.c.
| 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 }

| 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 }


| 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 }

| 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 }

| 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 }


| 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 }

| 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 }

| 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 }


Definiert in Zeile 12 der Datei skill_attributes.c.
| private nosave mapping skillattrs |
Definiert in Zeile 38 der Datei skill_attributes.c.
Wird benutzt von _query_skill_attr(), _set_skill_attr(), InternalModifySkillAttribute(), QuerySkillAttribute(), QuerySkillAttributeModifier(), RemoveSkillAttributeModifier() und UpdateSACache().
1.6.3