#include <hook.h>#include <living/skills.h>#include <thing/properties.h>#include <thing.h>#include <config.h>#include <health.h>#include <wizlevels.h>#include <language.h>#include <moving.h>#include <defines.h>#include <combat.h>#include <new_skills.h>#include <living.h>#include <scoremaster.h>#include <defuel.h>#include <debug_info.h>#include <events.h>
gehe zum Quellcode dieser Datei
Makrodefinitionen | |
| #define | NEED_PROTOTYPES |
| #define | ALCOHOL_VALUE(n) n |
Funktionen | |
| private void | DistributeExp (object enemy, int exp_to_give) |
| protected void | create () |
| public int | do_damage (int dam, mixed enemy) |
| private void | _transfer (object *obs, mixed dest, int flag) |
| public varargs void | transfer_all_to (mixed dest, int isnpc) |
| protected varargs void | create_kill_log_entry (string killer, object enemy) |
| protected object | GiveKillScore (object pl, int npcnum) |
| public int | death_suffering () |
| varargs protected int | second_life (object corpse) |
| public varargs void | die (int poisondeath, int extern) |
| public void | heal_self (int h) |
| public int | defuel_food () |
| public int | defuel_drink () |
| public void | reduce_spell_points (int h) |
| public void | restore_spell_points (int h) |
| public int | reduce_hit_points (int dam) |
| public int | restore_hit_points (int heal) |
| public varargs int | drink_alcohol (int strength, int testonly, string mytext) |
| public varargs int | drink_soft (int strength, int testonly, string mytext) |
| public varargs int | eat_food (int strength, int testonly, string mytext) |
| public int | buffer_hp (int val, int rate) |
| public int | buffer_sp (int val, int rate) |
| protected void | update_buffers () |
| public int | check_and_update_timed_key (int duration, string key) |
| protected void | expire_timing_map () |
| protected void | heart_beat () |
| public void | show_age () |
| public int | AddExp (int e) |
| static mixed * | _set_last_xp (mixed last) |
| static int | _set_align (int a) |
| static int | _set_hp (int hp) |
| static int | _set_sp (int sp) |
| static int | _set_alcohol (int n) |
| static int | _set_drink (int n) |
| static int | _set_food (int n) |
| static int | _set_poison (int n) |
| static int | _query_age () |
| static int | _set_xp (int xp) |
| static mixed | _set_die_hook (mixed hook) |
| static mapping | _query_enemy_damage () |
| static mapping | _query_timing_map () |
| public varargs int | consume (mapping cinfo, int testonly) |
Variablen | |
| int | age |
| nosave int | delay_alcohol |
| nosave int | delay_drink |
| nosave int | delay_food |
| nosave int | delay_heal |
| nosave int | delay_sp |
| nosave int | delay_poison |
| nosave int | drop_poison |
| nosave mapping | enemy_damage |
| nosave mapping | hp_buffer |
| nosave mapping | sp_buffer |
| nosave int | remove_me |
| int | nextdefueltimefood |
| int | nextdefueltimedrink |
| #define ALCOHOL_VALUE | ( | n | ) | n |
Definiert in Zeile 45 der Datei life.c.
Wird benutzt von drink_alcohol().
| static int _query_age | ( | ) | [static] |
| static mapping _query_enemy_damage | ( | ) | [static] |
Definiert in Zeile 1458 der Datei life.c.
Benutzt enemy_damage.
01459 { 01460 return copy(enemy_damage); 01461 }
| static mapping _query_timing_map | ( | ) | [static] |
Definiert in Zeile 1464 der Datei life.c.
Benutzt P_TIMING_MAP und Query().
01464 { 01465 return copy(Query(P_TIMING_MAP)); 01466 }

| static int _set_alcohol | ( | int | n | ) | [static] |
Definiert in Zeile 1273 der Datei life.c.
Benutzt F_VALUE, H_ALTERED, H_CANCELLED, H_HOOK_ALCOHOL, H_RETCODE, H_RETDATA, HookFlow(), P_ALCOHOL, P_GHOST, Query(), QueryProp() und Set().
01274 { 01275 if(!intp(n)) 01276 raise_error(sprintf( 01277 "_set_alcohol(): expected <int>, got %.50O\n", n)); 01278 01279 if (QueryProp(P_GHOST)) 01280 return Query(P_ALCOHOL, F_VALUE); 01281 01282 // nur Änderungen und Werte >=0 werden gesetzt... 01283 n = n < 0 ? 0 : n; 01284 int old = Query(P_ALCOHOL, F_VALUE); 01285 if ( old == n) 01286 return old; 01287 01288 // Hooks aufrufen 01289 int *ret = HookFlow(H_HOOK_ALCOHOL, n); 01290 // Bei Abbruch alten Wert zurueckgeben 01291 switch (ret[H_RETCODE]) { 01292 case H_CANCELLED: 01293 return old; 01294 case H_ALTERED: 01295 // sonst neuen Wert setzen 01296 if(!intp(ret[H_RETDATA])) 01297 raise_error(sprintf( 01298 "_set_alcohol(): data from HookFlow() != <int>: %.50O\n", 01299 ret[H_RETDATA])); 01300 n = ret[H_RETDATA]; 01301 n = n < 0 ? 0 : n; 01302 01303 // H_NO_MOD is fallthrough 01304 } 01305 01306 return Set(P_ALCOHOL, n, F_VALUE); 01307 }

| static int _set_align | ( | int | a | ) | [static] |
| static mixed _set_die_hook | ( | mixed | hook | ) | [static] |
Definiert in Zeile 1447 der Datei life.c.
Benutzt dtime(), F_VALUE, log_file, P_TMP_DIE_HOOK und Set().
01448 { 01449 if(hook && query_once_interactive(this_object())) 01450 log_file("DIE_HOOK", 01451 sprintf("%s : DIE_HOOK gesetzt von %O in %O (%s)\n", 01452 dtime(time())[5..], 01453 (previous_object(2) ? previous_object(2):previous_object(1)), 01454 this_object(),getuid(this_object()))); 01455 return Set(P_TMP_DIE_HOOK,hook, F_VALUE); 01456 }

| static int _set_drink | ( | int | n | ) | [static] |
Definiert in Zeile 1309 der Datei life.c.
Benutzt F_VALUE, H_ALTERED, H_CANCELLED, H_HOOK_DRINK, H_RETCODE, H_RETDATA, HookFlow(), P_DRINK, P_GHOST, Query(), QueryProp() und Set().
01310 { 01311 if(!intp(n)) 01312 raise_error(sprintf( 01313 "_set_drink(): expected <int>, got %.50O\n", n)); 01314 01315 if (QueryProp(P_GHOST)) 01316 return Query(P_DRINK, F_VALUE); 01317 01318 // nur Änderungen und Werte >=0 werden gesetzt... 01319 n = n < 0 ? 0 : n; 01320 int old = Query(P_DRINK, F_VALUE); 01321 if ( old == n) 01322 return old; 01323 01324 // Hooks aufrufen 01325 int *ret = HookFlow(H_HOOK_DRINK, n); 01326 // Bei Abbruch alten Wert zurueckgeben 01327 switch (ret[H_RETCODE]) { 01328 case H_CANCELLED: 01329 return old; 01330 case H_ALTERED: 01331 // sonst neuen Wert setzen 01332 if(!intp(ret[H_RETDATA])) 01333 raise_error(sprintf( 01334 "_set_drink(): data from HookFlow() != <int>: %.50O\n", 01335 ret[H_RETDATA])); 01336 n = ret[H_RETDATA]; 01337 n = n < 0 ? 0 : n; 01338 01339 // H_NO_MOD is fallthrough 01340 } 01341 01342 return Set(P_DRINK, n, F_VALUE); 01343 }

| static int _set_food | ( | int | n | ) | [static] |
Definiert in Zeile 1345 der Datei life.c.
Benutzt F_VALUE, H_ALTERED, H_CANCELLED, H_HOOK_FOOD, H_RETCODE, H_RETDATA, HookFlow(), P_FOOD, P_GHOST, Query(), QueryProp() und Set().
01346 { 01347 if(!intp(n)) 01348 raise_error(sprintf( 01349 "_set_food(): expected <int>, got %.50O\n", n)); 01350 01351 if (QueryProp(P_GHOST)) 01352 return Query(P_FOOD, F_VALUE); 01353 01354 // nur Änderungen und Werte >=0 werden gesetzt... 01355 n = n < 0 ? 0 : n; 01356 int old = Query(P_FOOD, F_VALUE); 01357 if ( old == n) 01358 return old; 01359 01360 // Hooks aufrufen 01361 int *ret = HookFlow(H_HOOK_FOOD, n); 01362 // Bei Abbruch alten Wert zurueckgeben 01363 switch (ret[H_RETCODE]) { 01364 case H_CANCELLED: 01365 return old; 01366 case H_ALTERED: 01367 // sonst neuen Wert setzen 01368 if(!intp(ret[H_RETDATA])) 01369 raise_error(sprintf( 01370 "_set_food(): data from HookFlow() != <int>: %.50O\n", 01371 ret[H_RETDATA])); 01372 n = ret[H_RETDATA]; 01373 n = n < 0 ? 0 : n; 01374 01375 // H_NO_MOD is fallthrough 01376 } 01377 01378 return Set(P_FOOD, n, F_VALUE); 01379 }

| static int _set_hp | ( | int | hp | ) | [static] |
Definiert in Zeile 1223 der Datei life.c.
Benutzt debug_info(), DINFO_TRACE, DIT_STR_CURRENT, log_file, P_GHOST, P_HP, P_MAX_HP, QueryProp() und Set().
01224 { 01225 //einige Leute schreiben floats in die P_HP. :-( 01226 if (!intp(hp)) { 01227 hp=to_int(hp); 01228 //ja, es ist teuer. Aber ich will wissen, wers ist. Kann vor 01229 //naechstem Reboot wieder raus. 01230 log_file("ILLEGAL_TYPE.log",sprintf( 01231 "Versuch, einen nicht-int in P_HP in %O zu schreiben: \n%O\n", 01232 this_object(), 01233 debug_info(DINFO_TRACE,DIT_STR_CURRENT))); 01234 } 01235 01236 if ( QueryProp(P_GHOST) ) 01237 return hp; 01238 01239 if ( hp < 0 ) 01240 return Set( P_HP, 0 ); 01241 01242 if ( hp > QueryProp(P_MAX_HP) ) 01243 return Set( P_HP, QueryProp(P_MAX_HP) ); 01244 01245 return Set( P_HP, hp ); 01246 }

| static mixed* _set_last_xp | ( | mixed | last | ) | [static] |
Definiert in Zeile 1205 der Datei life.c.
Benutzt P_LAST_XP, Query() und Set().
01206 { 01207 if ( !pointerp(last) || sizeof(last) != 2 || !stringp(last[0]) || 01208 !intp(last[1]) ) 01209 return Query(P_LAST_XP); 01210 else 01211 return Set( P_LAST_XP, last ); 01212 }

| static int _set_poison | ( | int | n | ) | [static] |
Definiert in Zeile 1381 der Datei life.c.
Benutzt drop_poison, dtime(), F_VALUE, H_ALTERED, H_CANCELLED, H_HOOK_POISON, H_RETCODE, H_RETDATA, HookFlow(), log_file, MAX_POISON, name, P_GHOST, P_POISON, Query(), QueryProp(), Set() und WER.
01382 { 01383 if(!intp(n)) 01384 raise_error(sprintf( 01385 "_set_poison(): expected <int>, got %.50O\n", n)); 01386 01387 if (QueryProp(P_GHOST)) 01388 return Query(P_POISON, F_VALUE); 01389 01390 n = (n<0 ? 0 : (n>MAX_POISON ? MAX_POISON : n)); 01391 01392 // nur >=0 zulassen. 01393 n = n < 0 ? 0 : n; 01394 01395 int old = Query(P_POISON, F_VALUE); 01396 if ( old == 0 && n == 0) 01397 return old; 01398 01399 // Hooks aufrufen 01400 int *ret = HookFlow(H_HOOK_POISON, n); 01401 // Bei Abbruch alten Wert zurueckgeben 01402 switch (ret[H_RETCODE]) { 01403 case H_CANCELLED: 01404 return old; 01405 case H_ALTERED: 01406 // sonst neuen Wert setzen 01407 if(!intp(ret[H_RETDATA])) 01408 raise_error(sprintf( 01409 "_set_poison(): data from HookFlow() != <int>: %.50O\n", 01410 ret[H_RETDATA])); 01411 n = ret[H_RETDATA]; 01412 n = n < 0 ? 0 : n; 01413 01414 // H_NO_MOD is fallthrough 01415 } 01416 01417 // Fuer die Selbstheilung. 01418 switch(n) { 01419 case 1: 01420 drop_poison = 40+random(16); 01421 break; 01422 case 2: 01423 drop_poison = 25+random(8); 01424 break; 01425 case 3: 01426 drop_poison = 18+random(4); 01427 break; 01428 } 01429 01430 log_file("POISON", sprintf("%s - %s: %d von %O (%s)\n", 01431 dtime(time())[5..], 01432 (query_once_interactive(this_object()) ? 01433 capitalize(geteuid(this_object())) : 01434 capitalize(name(WER))), 01435 n, 01436 (previous_object(2) ? previous_object(2) : previous_object(1)), 01437 (this_player() ? capitalize(geteuid(this_player())) : "???"))); 01438 01439 return Set(P_POISON, n, F_VALUE); 01440 01441 }

| static int _set_sp | ( | int | sp | ) | [static] |
Definiert in Zeile 1248 der Datei life.c.
Benutzt debug_info(), DINFO_TRACE, DIT_STR_CURRENT, log_file, P_GHOST, P_MAX_SP, P_SP, QueryProp() und Set().
01249 { 01250 //einige Leute schreiben floats in die P_HP. :-( 01251 if (!intp(sp)) { 01252 sp=to_int(sp); 01253 //ja, es ist teuer. Aber ich will wissen, wers ist. Kann vor 01254 //naechstem Reboot wieder raus. 01255 log_file("ILLEGAL_TYPE.log",sprintf( 01256 "Versuch, einen nicht-int in P_SP in %O zu schreiben: \n%O\n", 01257 this_object(), 01258 debug_info(DINFO_TRACE,DIT_STR_CURRENT))); 01259 } 01260 01261 if ( QueryProp(P_GHOST) ) 01262 return sp; 01263 01264 if ( sp < 0 ) 01265 return Set( P_SP, 0 ); 01266 01267 if ( sp > QueryProp(P_MAX_SP) ) 01268 return Set( P_SP, QueryProp(P_MAX_SP) ); 01269 01270 return Set( P_SP, sp ); 01271 }

| static int _set_xp | ( | int | xp | ) | [static] |
| private void _transfer | ( | object * | obs, | |
| mixed | dest, | |||
| int | flag | |||
| ) |
Definiert in Zeile 284 der Datei life.c.
Benutzt call_out(), i, move() und P_NEVERDROP.
00285 { int i; 00286 00287 i = sizeof(obs); 00288 00289 // Eine Schleife ist zwar langsamer als filter() o.ae., aber 00290 // selbst mit einer noch so schnellen Loesung kann leider nicht 00291 // ausgeschlossen werden, dass irgendwo ein too-long-eval-Bug dazwischen 00292 // kommt. Dazu sind die Kaempfe mit Gilden-NPCs etc. einfach zu teuer ... 00293 // Pruefung auf zerstoerte Objekte, da einige sich evtl. im NotifyPlayerDeath() 00294 // zerstoeren. 00295 while ( i && get_eval_cost() > 300000 ) 00296 if ( objectp(obs[--i]) && !obs[i]->QueryProp(P_NEVERDROP) ) 00297 // Jetzt wird's noch etwas teurer mit catch() - aber manche Sachen 00298 // duerfen einfach nicht buggen 00299 catch( obs[i]->move( dest, flag );publish ); 00300 00301 if ( i > 0 ) 00302 // Zuviel Rechenzeit verbraten, es muessen noch Objekte bewegt werden 00303 call_out( #'_transfer, 0, obs[0..i-1], dest, flag ); 00304 else { 00305 if ( remove_me ) 00306 remove(); 00307 } 00308 }

| public int AddExp | ( | int | e | ) |
Definiert in Zeile 1180 der Datei life.c.
Benutzt last, P_KILLS, P_LAST_XP, P_XP, Query(), QueryProp(), Set() und SetProp().
Wird benutzt von DeleteQuest() und GiveQuest().
01181 { 01182 int experience; 01183 string fn; 01184 mixed last; 01185 01186 experience = QueryProp(P_XP); 01187 01188 if ( QueryProp(P_KILLS) > 1 && e > 0 ) 01189 return experience; 01190 01191 fn = implode( explode( object_name( environment() || this_object() ), 01192 "/" )[0..<2], "/" ); 01193 01194 if ( pointerp(last = Query(P_LAST_XP)) && sizeof(last) == 2 && last[0] == fn ) 01195 Set( P_LAST_XP, ({ fn, last[1]+e }) ); 01196 else 01197 Set( P_LAST_XP, ({ fn, e }) ); 01198 01199 if ( (experience += e) < 0 ) 01200 experience = 0; 01201 01202 return SetProp( P_XP, experience ); 01203 }


| public int buffer_hp | ( | int | val, | |
| int | rate | |||
| ) |
Definiert in Zeile 829 der Datei life.c.
Benutzt hp_buffer, P_MAX_HP und QueryProp().
Wird benutzt von consume().
00830 { 00831 int dif; 00832 00833 if(val<=0 || rate<=0)return 0; 00834 if(val < rate)rate = val; 00835 if(rate>20) rate=20; 00836 00837 /* Check for BufferOverflow */ 00838 if((dif=(hp_buffer[0]+val)-QueryProp(P_MAX_HP)) > 0)val-=dif; 00839 if(val<=0)return 0; 00840 00841 hp_buffer[0] += val; 00842 hp_buffer[1+rate] += val; 00843 if(rate > hp_buffer[1])hp_buffer[1] = rate; 00844 00845 return hp_buffer[0]; 00846 }


| public int buffer_sp | ( | int | val, | |
| int | rate | |||
| ) |
Definiert in Zeile 848 der Datei life.c.
Benutzt P_MAX_SP, QueryProp() und sp_buffer.
Wird benutzt von consume().
00849 { 00850 int dif; 00851 00852 if(val<=0 || rate<=0)return 0; 00853 if(val < rate)rate = val; 00854 if(rate>20) rate=20; 00855 00856 /* Check for BufferOverflow */ 00857 if((dif=(sp_buffer[0]+val)-QueryProp(P_MAX_SP)) > 0)val-=dif; 00858 if(val<=0)return 0; 00859 00860 sp_buffer[0] += val; 00861 sp_buffer[1+rate] += val; 00862 if(rate > sp_buffer[1])sp_buffer[1] = rate; 00863 00864 return sp_buffer[0]; 00865 }


| public int check_and_update_timed_key | ( | int | duration, | |
| string | key | |||
| ) |
Definiert in Zeile 899 der Datei life.c.
Benutzt P_TIMING_MAP, Query() und SetProp().
00899 { 00900 mapping tmap; 00901 00902 if (!intp(duration) || !stringp(key)) 00903 return 0; 00904 if (!mappingp(tmap=Query(P_TIMING_MAP))) { 00905 tmap=([]); 00906 SetProp(P_TIMING_MAP, tmap); 00907 } 00908 if (duration < 0) 00909 return tmap[key]; 00910 if (tmap[key] >= time()) 00911 return tmap[key]; 00912 00913 tmap[key]=time()+duration; 00914 00915 // speichern per SetProp() unnoetig, da man das Mapping direkt aendert, 00916 // keine Kopie. 00917 //SetProp(P_TIMING_MAP, tmap); 00918 00919 return -1; 00920 }

| public varargs int consume | ( | mapping | cinfo, | |
| int | testonly | |||
| ) |
Definiert in Zeile 1484 der Datei life.c.
Benutzt buffer_hp(), buffer_sp(), drink_alcohol(), drink_soft(), eat_food(), H_ALLOWED_EFFECTS, H_ALTERED, H_CANCELLED, H_CONDITIONS, H_DISTRIBUTION, H_EFFECTS, H_HOOK_CONSUME, H_RETCODE, H_RETDATA, HC_HOOK_CANCELLATION, HC_MAX_ALCOHOL_REACHED, HC_MAX_DRINK_REACHED, HC_MAX_FOOD_REACHED, HD_INSTANT, HD_STANDARD, HookFlow(), P_ALCOHOL, P_DRINK, P_FOOD, P_HP, P_POISON, P_SP, QueryProp() und SetProp().
01485 { 01486 int retval = 0; 01487 // nur was tun, wenn auch Infos reinkommen 01488 if (mappingp(cinfo) && sizeof(cinfo)) { 01489 // Hooks aufrufen, sie aendern ggf. noch was in cinfo. 01490 mixed *hret = HookFlow(H_HOOK_CONSUME, ({cinfo, testonly}) ); 01491 switch(hret[H_RETCODE]) { 01492 case H_CANCELLED: 01493 return -HC_HOOK_CANCELLATION; 01494 case H_ALTERED: 01495 cinfo = hret[H_RETDATA]; 01496 } 01497 // Legacy-Mappings (flache) neben strukturierten Mappings zulassen 01498 // flache Kopien erzeugen (TODO?: und fuer Teilmappings nicht relevante 01499 // Eintraege loeschen) 01500 mapping conditions; 01501 if (mappingp(cinfo[H_CONDITIONS])) { 01502 conditions = copy(cinfo[H_CONDITIONS]); 01503 } else { 01504 conditions = copy(cinfo); 01505 } 01506 mapping effects; 01507 if (mappingp(cinfo[H_EFFECTS])) { 01508 effects = filter(cinfo[H_EFFECTS], (: member(H_ALLOWED_EFFECTS, $1) > -1 :)); 01509 } else { 01510 effects = filter(cinfo, (: member(H_ALLOWED_EFFECTS, $1) > -1 :)); 01511 } 01512 01513 // Bedingungen pruefen 01514 if (mappingp(conditions) && sizeof(conditions)) { 01515 // Bedingungen fuer Konsum auswerten 01516 if (conditions[P_FOOD] && !eat_food(conditions[P_FOOD], 1)) 01517 retval |= HC_MAX_FOOD_REACHED; 01518 else if (conditions[P_DRINK] && !drink_soft(conditions[P_DRINK], 1)) 01519 retval |= HC_MAX_DRINK_REACHED; 01520 else if (conditions[P_ALCOHOL] && !drink_alcohol(conditions[P_ALCOHOL], 1)) 01521 retval |= HC_MAX_ALCOHOL_REACHED; 01522 // retval negativ machen, damit Fehler leicht erkennbar ist 01523 retval = -retval; 01524 } 01525 // Bedingungen wurden abgearbeitet, jetzt die Heilung durchfuehren 01526 if (!retval) { 01527 if (!testonly) { 01528 // Bedingungen erfuellen, wenn alles passt und kein Test 01529 if (conditions[P_ALCOHOL]) 01530 drink_alcohol(conditions[P_ALCOHOL]); 01531 if (conditions[P_DRINK]) 01532 drink_soft(conditions[P_DRINK]); 01533 if (conditions[P_FOOD]) 01534 eat_food(conditions[P_FOOD]); 01535 // Und jetzt die Wirkungen 01536 if (effects[P_POISON]) 01537 SetProp(P_POISON, QueryProp(P_POISON) + effects[P_POISON]); 01538 // Und nun wirklich heilen 01539 switch (cinfo[H_DISTRIBUTION]) { 01540 case HD_INSTANT: 01541 map(effects, (: SetProp($1, QueryProp($1) + $2) :)); 01542 break; 01543 case 1..50: 01544 buffer_hp(effects[P_HP], cinfo[H_DISTRIBUTION]); 01545 buffer_sp(effects[P_SP], cinfo[H_DISTRIBUTION]); 01546 break; 01547 default: 01548 buffer_hp(effects[P_HP], HD_STANDARD); 01549 buffer_sp(effects[P_SP], HD_STANDARD); 01550 break; 01551 } 01552 } 01553 retval = 1; 01554 } 01555 } 01556 return retval; 01557 }

| protected void create | ( | ) |
Definiert in Zeile 73 der Datei life.c.
Benutzt ALCOHOL_DELAY, DRINK_DELAY, enemy_damage, F_MODE, F_MODE_AS, F_SET_METHOD, FOOD_DELAY, H_HOOK_ALCOHOL, H_HOOK_CONSUME, H_HOOK_DIE, H_HOOK_DRINK, H_HOOK_FOOD, H_HOOK_POISON, HEAL_DELAY, hp_buffer, nextdefueltimedrink, nextdefueltimefood, offerHook(), P_AGE, P_ALCOHOL, P_ALCOHOL_DELAY, P_ALIGN, P_CORPSE, P_DEAF, P_DEFUEL_AMOUNT_DRINK, P_DEFUEL_AMOUNT_FOOD, P_DEFUEL_LIMIT_DRINK, P_DEFUEL_LIMIT_FOOD, P_DEFUEL_TIME_DRINK, P_DEFUEL_TIME_FOOD, P_DRINK, P_DRINK_DELAY, P_FOOD, P_FOOD_DELAY, P_FROG, P_GHOST, P_HP, P_HP_DELAY, P_LAST_XP, P_POISON, P_POISON_DELAY, P_SP, P_SP_DELAY, P_XP, POISON_DELAY, PROTECTED, QueryProp(), SAVE, Set(), SetProp() und sp_buffer.
00074 { 00075 Set(P_GHOST, SAVE, F_MODE); 00076 Set(P_FROG, SAVE, F_MODE); 00077 Set(P_ALIGN, SAVE, F_MODE); 00078 Set(P_HP, SAVE, F_MODE); 00079 Set(P_SP, SAVE, F_MODE); 00080 Set(P_XP, SAVE, F_MODE); 00081 Set( P_LAST_XP, ({ "", 0 }) ); 00082 Set( P_LAST_XP, PROTECTED, F_MODE_AS ); 00083 00084 Set(P_ALCOHOL, SAVE, F_MODE); 00085 Set(P_DRINK, SAVE, F_MODE); 00086 Set(P_FOOD, SAVE, F_MODE); 00087 Set(P_POISON, SAVE, F_MODE); 00088 Set(P_DEAF, SAVE, F_MODE); 00089 00090 SetProp(P_FOOD_DELAY, FOOD_DELAY); 00091 SetProp(P_DRINK_DELAY, DRINK_DELAY); 00092 SetProp(P_ALCOHOL_DELAY, ALCOHOL_DELAY); 00093 SetProp(P_HP_DELAY,HEAL_DELAY); 00094 SetProp(P_SP_DELAY,HEAL_DELAY); 00095 SetProp(P_POISON_DELAY,POISON_DELAY); 00096 00097 Set(P_AGE, -1, F_SET_METHOD); 00098 Set(P_AGE, PROTECTED, F_MODE); 00099 SetProp(P_CORPSE, "/std/corpse"); 00100 00101 nextdefueltimefood=time()+QueryProp(P_DEFUEL_TIME_FOOD); 00102 nextdefueltimedrink=time()+QueryProp(P_DEFUEL_TIME_DRINK); 00103 00104 enemy_damage=([:2 ]); 00105 hp_buffer=([]); 00106 sp_buffer=([]); 00107 00108 SetProp(P_DEFUEL_LIMIT_FOOD,1); 00109 SetProp(P_DEFUEL_LIMIT_DRINK,1); 00110 SetProp(P_DEFUEL_TIME_FOOD,1); 00111 SetProp(P_DEFUEL_TIME_DRINK,1); 00112 SetProp(P_DEFUEL_AMOUNT_FOOD,1); 00113 SetProp(P_DEFUEL_AMOUNT_DRINK,1); 00114 00115 offerHook(H_HOOK_DIE,1); 00116 00117 offerHook(H_HOOK_FOOD,1); 00118 offerHook(H_HOOK_DRINK,1); 00119 offerHook(H_HOOK_ALCOHOL,1); 00120 offerHook(H_HOOK_POISON,1); 00121 offerHook(H_HOOK_CONSUME,1); 00122 }

| protected varargs void create_kill_log_entry | ( | string | killer, | |
| object | enemy | |||
| ) |
Definiert in Zeile 335 der Datei life.c.
Wird benutzt von heart_beat().
00335 { 00336 int level,lost_exp; 00337 00338 if ( (level=QueryProp(P_LEVEL))<20 || !IS_SEER(ME) ) 00339 lost_exp = QueryProp(P_XP)/3; 00340 else 00341 lost_exp = QueryProp(P_XP)/(level-17); 00342 00343 log_file("KILLS",sprintf("%s %s (%d,%d) %s\n", strftime("%e %b %H:%M"), 00344 capitalize(REAL_UID(ME)), level, lost_exp/1000, killer)); 00345 00346 catch(call_other("/p/service/rochus/killstat/killmaster","AddKill",enemy); 00347 publish); 00348 }

| public int death_suffering | ( | ) |
Definiert in Zeile 407 der Datei life.c.
Wird benutzt von QuerySkillAttribute() und score().

| public int defuel_drink | ( | ) |
Definiert in Zeile 682 der Datei life.c.
Benutzt alc, DEFUEL_TOO_LOW, DEFUEL_TOO_SOON, nextdefueltimedrink, NO_DEFUEL, P_ALCOHOL, P_DEFUEL_AMOUNT_DRINK, P_DEFUEL_LIMIT_DRINK, P_DEFUEL_TIME_DRINK, P_DRINK, P_MAX_ALCOHOL, P_MAX_DRINK, P_WEIGHT, QueryProp() und SetProp().
Wird benutzt von defuel_drink().
00683 { 00684 int alc, drink; 00685 00686 drink=QueryProp(P_DRINK); 00687 00688 // wenn spieler kein drink hat: return 0 00689 if ( !drink ) 00690 return NO_DEFUEL; 00691 00692 // wenn spieler unter enttank-grenze: return -1 00693 if ( drink < QueryProp(P_DEFUEL_LIMIT_DRINK) ) 00694 return DEFUEL_TOO_LOW; 00695 00696 // wenn letztes enttanken nicht lange genug zurueckliegt: return -2 00697 if ( time() < nextdefueltimedrink ) 00698 return DEFUEL_TOO_SOON; 00699 00700 drink=to_int(((drink*QueryProp(P_DEFUEL_AMOUNT_DRINK))/2)); 00701 drink+=random(drink); 00702 00703 // sicherheitshalber 00704 if ( drink > QueryProp(P_DRINK) ) 00705 drink=QueryProp(P_DRINK); 00706 00707 SetProp(P_DRINK,(QueryProp(P_DRINK)-drink)); 00708 00709 // jedes fluessige Enttanken macht auch etwas nuechterner :^) 00710 // bei sehr kleinen Mengen enttankt man keinen Alkohol 00711 // ansonsten in Abhaengigkeit von enttankter Menge, P_ALCOHOL und P_WEIGHT 00712 00713 if ( drink > 9 && QueryProp(P_ALCOHOL) > 0 ) 00714 { 00715 alc=(to_int(exp(log(1.1)*(drink)))* 00716 to_int(exp(log(0.67)*(QueryProp(P_ALCOHOL)))))/ 00717 (QueryProp(P_MAX_DRINK)*QueryProp(P_MAX_ALCOHOL))* 00718 (to_int(QueryProp(P_WEIGHT)/1000)); 00719 00720 SetProp(P_ALCOHOL,QueryProp(P_ALCOHOL)-(alc+random(alc))); 00721 } 00722 00723 nextdefueltimedrink=time()+QueryProp(P_DEFUEL_TIME_DRINK); 00724 00725 return drink; 00726 }


| public int defuel_food | ( | ) |
Definiert in Zeile 640 der Datei life.c.
Benutzt DEFUEL_TOO_LOW, DEFUEL_TOO_SOON, food, nextdefueltimefood, NO_DEFUEL, P_DEFUEL_AMOUNT_FOOD, P_DEFUEL_LIMIT_FOOD, P_DEFUEL_TIME_FOOD, P_FOOD, QueryProp() und SetProp().
Wird benutzt von defuel_food().
00641 { 00642 int food; 00643 00644 food=QueryProp(P_FOOD); 00645 00646 // wenn spieler kein food hat: return 0 00647 if ( !food ) 00648 return NO_DEFUEL; 00649 00650 // wenn spieler unter enttank-grenze: return -1 00651 if ( food < QueryProp(P_DEFUEL_LIMIT_FOOD) ) 00652 return DEFUEL_TOO_LOW; 00653 00654 // wenn letztes enttanken nicht lange genug zurueckliegt: return -2 00655 if ( time() < nextdefueltimefood ) 00656 return DEFUEL_TOO_SOON; 00657 00658 food=to_int(((food*QueryProp(P_DEFUEL_AMOUNT_FOOD))/2)); 00659 food+=random(food); 00660 00661 // sicherheitshalber 00662 if ( food > QueryProp(P_FOOD) ) 00663 food=QueryProp(P_FOOD); 00664 00665 SetProp(P_FOOD,(QueryProp(P_FOOD)-food)); 00666 00667 nextdefueltimefood=time()+QueryProp(P_DEFUEL_TIME_FOOD); 00668 00669 return food; 00670 }


| public varargs void die | ( | int | poisondeath, | |
| int | extern | |||
| ) |
Definiert in Zeile 416 der Datei life.c.
00417 { object corpse; 00418 string die_msg, tmp; 00419 mixed res; 00420 mixed hookData; 00421 mixed hookRes; 00422 00423 if ( !objectp(this_object()) || QueryProp(P_GHOST) ) 00424 return; // Ghosts dont die ... 00425 00426 if ( res = QueryProp(P_TMP_DIE_HOOK) ){ 00427 if ( pointerp(res) && sizeof(res)>=3 00428 && intp(res[0]) && time()<res[0] 00429 && objectp(res[1]) && stringp(res[2]) ) 00430 { 00431 if ( res = call_other( res[1], res[2], poisondeath ) ) 00432 return; 00433 } 00434 else 00435 SetProp(P_TMP_DIE_HOOK,0); 00436 } 00437 00438 // trigger die hook 00439 hookData=poisondeath; 00440 hookRes=HookFlow(H_HOOK_DIE,hookData); 00441 if (pointerp(hookRes) && sizeof(hookRes)>H_RETDATA){ 00442 if(hookRes[H_RETCODE]==H_CANCELLED){ 00443 return; 00444 } 00445 else if (hookRes[H_RETCODE]==H_ALTERED) 00446 poisondeath = hookRes[H_RETDATA]; 00447 } 00448 00449 if ( IS_LEARNING(ME) && query_once_interactive(ME) ){ 00450 tell_object( ME, "Sei froh dass Du unsterblich bist, sonst waere es " 00451 "eben Dein Ende gewesen.\n"); 00452 return; 00453 } 00454 00455 // direkt von extern aufgerufen und nicht ueber heart_beat() oder 00456 // do_damage() hierher gelangt? 00457 if (extern_call() && previous_object() != this_object()) { 00458 extern=1; 00459 SetProp(P_KILLER, previous_object()); 00460 } 00461 00462 // Gegner befrieden. 00463 map_objects( QueryEnemies()[0], "StopHuntFor", ME, 1 ); 00464 StopHuntingMode(1); 00465 00466 // Falls die() direkt aufgerufen wurde und dies ein Spieler ist, muss das 00467 // die() noch Eintraege in /log/KILLS via create_kill_log_entry bzw. in 00468 // /log/KILLER erstellen. 00469 if ( query_once_interactive(ME) && extern ) 00470 { 00471 object killer = QueryProp(P_KILLER) 00472 || previous_object() || this_interactive() || this_player(); 00473 if ( killer && !query_once_interactive(killer) ) 00474 { 00475 tmp = explode( object_name(killer), "#")[0] + " (direkt !)"; 00476 00477 create_kill_log_entry( tmp + " (" + REAL_UID(killer) + ")", killer ); 00478 } 00479 else if ( killer && !QueryProp(P_TESTPLAYER) && !IS_LEARNER(ME) ) 00480 { 00481 log_file( "KILLER", sprintf( "%s %s (%d/%d) toetete %s (%d/%d)\n", 00482 ctime(time()), 00483 capitalize(getuid(killer)), 00484 query_wiz_level(killer), 00485 killer->QueryProp(P_LEVEL), 00486 capitalize(getuid(ME)), 00487 query_wiz_level(ME), 00488 QueryProp(P_LEVEL) ) ); 00489 00490 killer->SetProp( P_KILLS, -1 ); 00491 } 00492 } 00493 00494 // Bei NPC EKs vergeben und ggf. in der Gilde des Killers und im Raum 00495 // NPC_Killed_By() rufen. 00496 if ( !query_once_interactive(ME) ) 00497 { 00498 object killer = ((object) QueryProp(P_KILLER)) || previous_object() || 00499 this_interactive() || this_player(); 00500 00501 if ( killer && query_once_interactive(killer) ) 00502 { 00503 if (stringp(res=killer->QueryProp(P_GUILD)) 00504 && objectp(res=find_object("/gilden/"+res))) 00505 res->NPC_Killed_By(killer); 00506 00507 if (environment()) 00508 environment()->NPC_Killed_By(killer); 00509 00510 res = QueryProp(P_XP); 00511 res = (res < SCORE_LOW_MARK) ? 0 : ((res > SCORE_HIGH_MARK) ? 2 : 1); 00512 if ( !QueryProp(P_NO_SCORE) && !IS_LEARNER(killer) && 00513 // !killer->QueryProp(P_TESTPLAYER) && 00514 pointerp( res = SCOREMASTER->QueryNPC(res)) ) 00515 GiveKillScore( killer, res[0] ); 00516 } 00517 } 00518 00519 if( !(die_msg = QueryProp(P_DIE_MSG)) ) 00520 if (QueryProp(P_PLURAL)) 00521 die_msg = " fallen tot zu Boden.\n"; 00522 else 00523 die_msg = " faellt tot zu Boden.\n"; 00524 00525 if ( poisondeath ) 00526 { 00527 Set( P_LAST_DAMTYPES, ({ DT_POISON }) ); 00528 Set( P_LAST_DAMTIME, time() ); 00529 Set( P_LAST_DAMAGE, 1 ); 00530 die_msg = " wird von Gift hinweggerafft und kippt um.\n"; 00531 } 00532 00533 say( capitalize(name(WER,1)) + die_msg ); 00534 00535 // Wenn keine Leiche, dann Kram ins Env legen. 00536 if ( QueryProp(P_NOCORPSE) || !(tmp = QueryProp(P_CORPSE)) 00537 || catch(corpse = clone_object(tmp);publish) 00538 || !objectp(corpse) ) 00539 { 00540 // Magier oder Testspieler behalten ihre Ausruestung. 00541 // Sonst kaemen u.U. Spieler an Magiertools etc. heran 00542 if ( !(IS_LEARNER(ME) || (tmp = Query(P_TESTPLAYER)) && 00543 (!stringp(tmp) || IS_LEARNER( lower_case(tmp) ))) ) 00544 transfer_all_to( environment(), 0 ); 00545 else 00546 // Aber sie ziehen sich aus. 00547 filter_objects(QueryProp(P_ARMOURS),"DoUnwear",1,1); 00548 } 00549 else 00550 // sonst in die Leiche legen. 00551 { 00552 corpse->Identify(ME); 00553 corpse->move( environment(), M_NOCHECK|M_SILENT ); 00554 // Magier oder Testspieler behalten ihre Ausruestung. 00555 // Sonst kaemen u.U. Spieler an Magiertools etc. heran 00556 if ( !(IS_LEARNER(ME) || (tmp = Query(P_TESTPLAYER)) && 00557 (!stringp(tmp) || IS_LEARNER( lower_case(tmp) ))) ) 00558 transfer_all_to( corpse, !query_once_interactive(ME) ); 00559 else 00560 // Aber sie ziehen sich aus. 00561 filter_objects(QueryProp(P_ARMOURS),"DoUnwear",1,1); 00562 } 00563 00564 if ( query_once_interactive(ME) ) { 00565 Set( P_DEADS, Query(P_DEADS) + 1 ); 00566 // Spieler-Tod-event ausloesen 00567 EVENTD->TriggerEvent(EVT_LIB_PLAYER_DEATH, ([ 00568 E_OBJECT: ME, E_PLNAME: getuid(ME), 00569 E_ENVIRONMENT: environment(), E_TIME: time(), 00570 P_KILLER: QueryProp(P_KILLER), 00571 P_LAST_DAMAGE: QueryProp(P_LAST_DAMAGE), 00572 P_LAST_DAMTYPES: copy(QueryProp(P_LAST_DAMTYPES)), 00573 E_EXTERNAL_DEATH: extern, 00574 E_POISON_DEATH: poisondeath, 00575 E_CORPSE: (objectp(corpse)?corpse:0) ]) ); 00576 } 00577 else { 00578 // NPC-Todes-Event ausloesen. Div. Mappings/Arrays werden nicht kopiert, 00579 // weil der NPC ja jetzt eh zerstoert wird. 00580 mapping data = ([ 00581 E_OBNAME: object_name(ME), 00582 E_ENVIRONMENT: environment(), E_TIME: time(), 00583 P_NAME: QueryProp(P_NAME), 00584 P_KILLER: QueryProp(P_KILLER), 00585 P_ENEMY_DAMAGE: QueryProp(P_ENEMY_DAMAGE), 00586 P_LAST_DAMAGE: QueryProp(P_LAST_DAMAGE), 00587 P_LAST_DAMTYPES: QueryProp(P_LAST_DAMTYPES), 00588 E_EXTERNAL_DEATH: extern, 00589 E_POISON_DEATH: poisondeath, 00590 E_CORPSE: (objectp(corpse)?corpse:0), 00591 P_XP: QueryProp(P_XP), 00592 P_ATTRIBUTES: QueryProp(P_ATTRIBUTES), 00593 P_MAX_HP: QueryProp(P_MAX_HP), 00594 P_HANDS: QueryProp(P_HANDS), 00595 P_ALIGN: QueryProp(P_ALIGN), 00596 P_RACE: QueryProp(P_RACE), 00597 P_CLASS: QueryProp(P_CLASS), 00598 ]); 00599 EVENTD->TriggerEvent(EVT_LIB_NPC_DEATH(""), data); 00600 EVENTD->TriggerEvent( 00601 EVT_LIB_NPC_DEATH(load_name(ME)), data); 00602 } 00603 00604 // transfer_all_to() ist evtl. (wenn zuviele Objekte bewegt werden mussten) 00605 // noch nicht ganz fertig und wird per call_out() den Rest erledigen. 00606 // Sollte die Leiche dann nicht mehr existieren, verbleiben die restlichen 00607 // Objekte im Spieler. 00608 // Es bleiben aber auf jeden Fall noch rund 300k Eval-Ticks ueber, damit 00609 // kein Spieler dank "evalcost too high" ungeschoren davon kommt. 00610 if ( !(second_life(corpse)) ) 00611 { 00612 Set( P_GHOST, 1 ); // Fuer korrekte Ausgabe auf Teamkanal. 00613 00614 if ( find_call_out(#'_transfer) == -1 ) 00615 // Falls kein call_out() mehr laeuft, sofort destructen ... 00616 remove(); 00617 else 00618 // ... ansonsten vormerken 00619 remove_me = 1; 00620 } 00621 }
| private void DistributeExp | ( | object | enemy, | |
| int | exp_to_give | |||
| ) |
Definiert in Zeile 124 der Datei life.c.
Benutzt enemy_damage, ex, inv(), m_delete() und ob().
Wird benutzt von do_damage().
00124 { 00125 int total_damage, tmp, ex; 00126 mapping present_enemies; 00127 00128 if ( exp_to_give<=0 ) 00129 return; 00130 00131 mapping endmg=deep_copy(enemy_damage); 00132 00133 // Mitglieder im Team des Killers bekommen: 00134 // 00135 // Gesamtanteil des Teams 00136 // Eigenen Anteil + ---------------------- 00137 // Anzahl Teammitglieder 00138 // --------------------------------------- 00139 // 2 00140 // 00141 object *inv = enemy->TeamMembers(); 00142 if ( pointerp(inv) ) 00143 { 00144 present_enemies=m_allocate(sizeof(inv), 1); 00145 foreach(object ob: inv) 00146 { 00147 if ( objectp(ob) && (environment(ob)==environment()) ) 00148 { 00149 tmp=endmg[object_name(ob)]; 00150 total_damage+=tmp; 00151 present_enemies[ob] = tmp/2; 00152 efun::m_delete(endmg,object_name(ob)); //s.u. 00153 } 00154 } 00155 int mitglieder = sizeof(present_enemies); 00156 if ( mitglieder ) 00157 { 00158 tmp=total_damage/(2*mitglieder); 00159 foreach(object ob, int punkte: &present_enemies) 00160 punkte += tmp; 00161 } 00162 } 00163 else { 00164 // ohne Team wird trotzdem ein Mapping gebraucht. Da Groessenveraenderung 00165 // rel. teuer sind, kann einfach mal fuer 3 Eintraege Platz reservieren. 00166 present_enemies=m_allocate(3, 1); 00167 } 00168 // Und noch die Lebewesen im Raum ohne Team. 00169 foreach(object ob: all_inventory(environment())) 00170 { 00171 if ( tmp=endmg[object_name(ob)] ) 00172 { 00173 total_damage += tmp; 00174 present_enemies[ob] = tmp; 00175 efun::m_delete(endmg,object_name(ob)); // Nur einmal pro Leben Punkte :) 00176 } 00177 } 00178 if ( !total_damage ) 00179 { 00180 enemy->AddExp(exp_to_give); 00181 } 00182 else 00183 { 00184 foreach(object ob, int damage: present_enemies) 00185 { 00186 if ( !objectp(ob) ) 00187 continue; 00188 if ( query_once_interactive(ob) && ( !interactive(ob) 00189 || (query_idle(ob)>600) ) ) 00190 continue; 00191 //exp_to_give*present_enemies[i][1]/total_damage gibt bei viel Schaden 00192 //einen numerical overflow. Daher muessen wir hier wohl doch 00193 //zwischenzeitlich mit floats rechnen, auch wenn das 0-1 XP Verlust 00194 //durch float->int-Konversion gibt. (ceil() lohnt sich IMHO nicht.) 00195 ex = (int)(exp_to_give*((float)damage/(float)total_damage)); 00196 ob->AddExp(ex); 00197 } 00198 } 00199 }


| public int do_damage | ( | int | dam, | |
| mixed | enemy | |||
| ) |
Definiert in Zeile 209 der Datei life.c.
Benutzt die(), DistributeExp(), dtime(), enemy_damage, log_file, ME, P_ALIGN, P_ENABLE_IN_ATTACK_OUT, P_GHOST, P_HELPER_NPC, P_HP, P_KILLER, P_LAST_MOVE, P_MAX_HP, P_NO_ATTACK, P_NO_XP, P_TOTAL_WC, P_XP, QueryProp() und SetProp().
00210 { int hit_point,al,al2; 00211 00212 if ( extern_call() 00213 && objectp(enemy) 00214 && living(enemy) 00215 && !QueryProp(P_ENABLE_IN_ATTACK_OUT)) 00216 { 00217 al=time()-enemy->QueryProp(P_LAST_MOVE); 00218 if (al<3) // Erste Kampfrunde nach Betreten des Raumes? 00219 dam/=(4-al); // Gegen Rein-Feuerball-Raus-Taktik 00220 } 00221 00222 if ( QueryProp(P_GHOST) || QueryProp(P_NO_ATTACK) || (dam<=0) 00223 || ( objectp(enemy) 00224 && ( enemy->QueryProp(P_GHOST) 00225 || enemy->QueryProp(P_NO_ATTACK) ) ) ) 00226 return 0; 00227 00228 hit_point = QueryProp(P_HP)-dam; 00229 00230 if ( QueryProp(P_XP) && objectp(enemy) ) 00231 { 00232 if ( !QueryProp(P_NO_XP) ) 00233 enemy->AddExp(dam*(int)QueryProp(P_TOTAL_WC)/10); 00234 } 00235 00236 if (living(enemy)) { 00237 string enname = object_name(enemy); 00238 // Hmpf. Blueprints sind doof. Die Chance ist zwar gering, aber koennte 00239 // sein, dass ein Unique-NPC mit zwei verschiedenen Spielern am gleichen 00240 // NPC metzelt. 00241 // TODO: MHmm. wie gross ist das Risiko wirklich? 00242 //if (!clonep(enemy)) 00243 // enname = enname + "_" + to_string(object_time(enemy)); 00244 // nur wenn gegner NPC ist und noch nicht drinsteht: Daten aus 00245 // P_HELPER_NPC auswerten 00246 if (!member(enemy_damage,enemy) && !query_once_interactive(enemy)) { 00247 mixed helper = enemy->QueryProp(P_HELPER_NPC); 00248 if (pointerp(helper) && objectp(helper[0])) 00249 enemy_damage[enname,1] = helper[0]; 00250 } 00251 enemy_damage[enname,0]+=dam; 00252 } 00253 00254 SetProp(P_HP, hit_point); 00255 00256 if ( hit_point<0 ) 00257 { 00258 if ( enemy ) 00259 { 00260 enemy->StopHuntFor(ME,1); 00261 if ( !QueryProp(P_NO_XP) ) 00262 DistributeExp(enemy,QueryProp(P_XP)/100); 00263 if ( !query_once_interactive(ME) ) 00264 log_file ("NPC_XP", sprintf( 00265 "[%s] %s, XP: %d, HP*WC: %d, Killer: %s\n", 00266 dtime(time()), object_name(ME), (QueryProp(P_XP)/100), 00267 QueryProp(P_TOTAL_WC)*QueryProp(P_MAX_HP)/10, 00268 enemy->name()||"NoName" )); 00269 al = QueryProp(P_ALIGN)/50 + enemy->QueryProp(P_ALIGN)/200; 00270 if (al>20) 00271 al=20; 00272 else if(al<-20) 00273 al=-20; 00274 enemy->SetProp(P_ALIGN,enemy->QueryProp(P_ALIGN)-al); 00275 } 00276 SetProp(P_KILLER, enemy); 00277 00278 die(); 00279 } 00280 return dam; 00281 }

| public varargs int drink_alcohol | ( | int | strength, | |
| int | testonly, | |||
| string | mytext | |||
| ) |
Definiert in Zeile 770 der Datei life.c.
Benutzt add, alc, ALCOHOL_VALUE, IS_LEARNING, ME, P_ALCOHOL, P_MAX_ALCOHOL, QueryProp(), SetProp(), SI_SKILLARG, SI_TESTFLAG, SK_BOOZE und UseSkill().
Wird benutzt von consume().
00771 { int alc,add,res; 00772 00773 add=ALCOHOL_VALUE(strength); 00774 res=UseSkill(SK_BOOZE,([ 00775 SI_SKILLARG : add, 00776 SI_TESTFLAG : 1])); // Kann der Spieler gut saufen? 00777 if (intp(res) && res>0) add=res; 00778 alc=QueryProp(P_ALCOHOL)+add; 00779 if ((alc >= QueryProp(P_MAX_ALCOHOL)) && !IS_LEARNING(this_object())){ 00780 if(!testonly) 00781 tell_object(ME,mytext||"So ein Pech, Du hast alles verschuettet.\n"); 00782 return 0; 00783 } 00784 if(testonly)return 1; 00785 UseSkill(SK_BOOZE,([ SI_SKILLARG : ALCOHOL_VALUE(strength) ])); 00786 if(alc < 0) alc = 0; 00787 if(!alc) tell_object(ME, "Du bist stocknuechtern.\n"); 00788 SetProp(P_ALCOHOL, alc); 00789 return 1; 00790 }


| public varargs int drink_soft | ( | int | strength, | |
| int | testonly, | |||
| string | mytext | |||
| ) |
Definiert in Zeile 792 der Datei life.c.
Benutzt DRINK_VALUE, IS_LEARNING, ME, P_DRINK, P_MAX_DRINK, QueryProp() und SetProp().
Wird benutzt von consume().
00793 { int soaked; 00794 00795 soaked = QueryProp(P_DRINK); 00796 if((soaked + strength > QueryProp(P_MAX_DRINK)) && 00797 !IS_LEARNING(this_object())){ 00798 if(!testonly) 00799 tell_object(ME, mytext|| 00800 "Nee, so viel kannst Du momentan echt nicht trinken.\n" ); 00801 return 0; 00802 } 00803 if(testonly)return 1; 00804 if((soaked += DRINK_VALUE(strength)) < 0) soaked = 0; 00805 if(!soaked) tell_object(ME, "Dir klebt die Zunge am Gaumen.\n"); 00806 SetProp(P_DRINK, soaked); 00807 return 1; 00808 }


| public varargs int eat_food | ( | int | strength, | |
| int | testonly, | |||
| string | mytext | |||
| ) |
Definiert in Zeile 810 der Datei life.c.
Benutzt FOOD_VALUE, IS_LEARNING, ME, P_FOOD, P_MAX_FOOD, QueryProp() und SetProp().
Wird benutzt von consume().
00811 { int stuffed; 00812 00813 stuffed = QueryProp(P_FOOD); 00814 if ((stuffed + strength > QueryProp(P_MAX_FOOD)) && 00815 !IS_LEARNING(this_object())) 00816 { 00817 if(!testonly)tell_object(ME, mytext|| 00818 "Das ist viel zu viel fuer Dich! Wie waers mit etwas leichterem?\n"); 00819 return 0; 00820 } 00821 if(testonly)return 1; 00822 stuffed += FOOD_VALUE(strength); 00823 if(stuffed < 0) stuffed = 0; 00824 if(!stuffed) tell_object(ME, "Was rumpelt denn da in Deinem Bauch?\n"); 00825 SetProp(P_FOOD, stuffed); 00826 return 1; 00827 }


| protected void expire_timing_map | ( | ) |
Definiert in Zeile 922 der Datei life.c.
Benutzt F_VALUE, m_delete(), P_TIMING_MAP und Query().
00922 { 00923 00924 mapping tmap = Query(P_TIMING_MAP, F_VALUE); 00925 if (!mappingp(tmap) || !sizeof(tmap)) 00926 return; 00927 foreach(string key, int endtime: tmap) { 00928 if (endtime < time()) 00929 efun::m_delete(tmap, key); 00930 } 00931 // speichern per SetProp() unnoetig, da man das Mapping direkt aendert, 00932 // keine Kopie. 00933 }

| protected object GiveKillScore | ( | object | pl, | |
| int | npcnum | |||
| ) |
Definiert in Zeile 350 der Datei life.c.
00351 { 00352 // Stufenpunkt fuer den Kill vergeben. 00353 // Falls der Killer den Punkt schon hat, wird 00354 // zufaellig ein Mitglied seines Teams ausgewaehlt 00355 // und diesem der Punkt gegeben. 00356 object *obs,ob; 00357 mixed *fr; 00358 int i,j,sz; 00359 00360 if ( pointerp(obs=pl->TeamMembers()) && (member(obs,pl)>=0) ) 00361 { 00362 if ( !pointerp(fr=pl->PresentTeamRows()) 00363 || !sizeof(fr) 00364 || !pointerp(fr=fr[0])) // Erste Reihe des Teams 00365 fr=({}); 00366 fr-=({pl,0}); 00367 obs-=({pl,0}); 00368 obs-=fr; 00369 i=sz=sizeof(obs); // restliche Teammitglieder in zufaelliger Reihenfolge: 00370 for ( --i ; i>=0 ; i-- ) 00371 { 00372 j=random(sz); 00373 ob=obs[j]; 00374 obs[j]=obs[0]; 00375 obs[0]=ob; 00376 } 00377 i=sz=sizeof(fr); // Erste Reihe in zufaelliger Reihenfolge: 00378 for ( --i ; i>=0 ; i-- ) 00379 { 00380 j=random(sz); 00381 ob=fr[j]; 00382 fr[j]=fr[0]; 00383 fr[0]=ob; 00384 } 00385 00386 obs+=fr; // Erste Reihe wird vor Rest getestet 00387 obs+=({pl}); // Killer wird als erstes getestet 00388 } 00389 else 00390 { 00391 obs=({pl}); 00392 } 00393 for ( i=sizeof(obs)-1 ; i>=0 ; i-- ) 00394 if ( objectp(ob=obs[i] ) 00395 && interactive(ob) // Nur netztot dabei stehen gilt nicht :) 00396 && query_idle(ob)<600 // gegen Leute die sich nur mitschleppen lassen 00397 && environment(ob)==environment(pl) // Nur anwesende Teammitglieder 00398 && !IS_LEARNER(ob) 00399 // && !ob->QueryProp(P_TESTPLAYER) 00400 && !(SCOREMASTER->HasKill(ob,ME)) ) 00401 return SCOREMASTER->GiveKill(ob,npcnum),ob; 00402 00403 return SCOREMASTER->GiveKill(pl,npcnum),pl; 00404 }
| public void heal_self | ( | int | h | ) |
Definiert in Zeile 623 der Datei life.c.
Benutzt P_HP, P_SP, QueryProp() und SetProp().
Wird benutzt von SelectWhich().
00624 { 00625 if ( h<=0 ) 00626 return; 00627 SetProp(P_HP, QueryProp(P_HP)+h); 00628 SetProp(P_SP, QueryProp(P_SP)+h); 00629 }


| protected void heart_beat | ( | ) |
Definiert in Zeile 935 der Datei life.c.
Benutzt age, alc, ALC_EFFECT_AREA_ENV, ALC_EFFECT_AREA_GUILD, ALC_EFFECT_HICK, ALC_EFFECT_LOOKDRUNK, ALC_EFFECT_RUELPS, ALC_EFFECT_STUMBLE, attribute_hb(), break_string(), create_kill_log_entry(), delay_alcohol, delay_drink, delay_food, delay_heal, delay_poison, delay_sp, die(), drop_poison, FEMALE, gilde, hp_buffer, ME, name, NO_REG_ALCOHOL, NO_REG_BUFFER_HP, NO_REG_BUFFER_SP, NO_REG_DRINK, NO_REG_FOOD, NO_REG_HP, NO_REG_SP, ob(), P_ALCOHOL, P_ALCOHOL_DELAY, P_DRINK, P_DRINK_DELAY, P_FOOD, P_FOOD_DELAY, P_GHOST, P_GUILD, P_HP, P_HP_DELAY, P_KILLER, P_MAX_ALCOHOL, P_MAX_HP, P_NO_REGENERATION, P_POISON, P_POISON_DELAY, P_SP, P_SP_DELAY, POISON_MERCY_DELAY, QueryPossPronoun(), QueryProp(), Set(), SetProp(), log_buffer_s::sp, sp_buffer, update_buffers(), WEN und WER.
00936 { 00937 int hpoison, alc, rate, val, rlock, hp, sp; 00938 00939 if ( !this_object() ) 00940 return; 00941 00942 age++; 00943 00944 attribute_hb(); 00945 00946 // Als Geist leidet man nicht unter so weltlichen Dingen wie 00947 // Alkohol, Gift&Co ... 00948 if ( QueryProp(P_GHOST) ) 00949 return; 00950 00951 hpoison = QueryProp(P_POISON); 00952 rlock = QueryProp(P_NO_REGENERATION); 00953 hp = QueryProp(P_HP); 00954 sp = QueryProp(P_SP); 00955 00956 if ( (alc = QueryProp(P_ALCOHOL)) && !random(40) ){ 00957 int n; 00958 string gilde; 00959 object ob; 00960 00961 n = random( 5 * (alc - 1)/QueryProp(P_MAX_ALCOHOL) ); 00962 00963 switch (n){ 00964 case ALC_EFFECT_HICK: 00965 say( capitalize(name( WER, 1 )) + " sagt: <Hick>!\n" ); 00966 write( "<Hick>! Oh, Tschuldigung.\n" ); 00967 break; 00968 00969 case ALC_EFFECT_STUMBLE: 00970 say( capitalize(name( WER, 1 )) + " stolpert ueber " + 00971 QueryPossPronoun( FEMALE, WEN ) + " Fuesse.\n" ); 00972 write( "Du stolperst.\n" ); 00973 break; 00974 00975 case ALC_EFFECT_LOOKDRUNK: 00976 say( capitalize(name( WER, 1 )) + " sieht betrunken aus.\n" ); 00977 write( "Du fuehlst Dich benommen.\n" ); 00978 break; 00979 00980 case ALC_EFFECT_RUELPS: 00981 say( capitalize(name( WER, 1 )) + " ruelpst.\n" ); 00982 write( "Du ruelpst.\n" ); 00983 break; 00984 } 00985 00986 if ( stringp(gilde = QueryProp(P_GUILD)) 00987 && objectp(ob = find_object( "/gilden/" + gilde )) ) 00988 ob->InformAlcoholEffect( ME, n, ALC_EFFECT_AREA_GUILD ); 00989 00990 if ( environment() ) 00991 environment()->InformAlcoholEffect( ME, n, ALC_EFFECT_AREA_ENV ); 00992 } 00993 00994 if ( alc && (--delay_alcohol < 0) 00995 && !(rlock & NO_REG_ALCOHOL) ){ 00996 00997 SetProp( P_ALCOHOL, alc - 1 ); 00998 00999 if ( !hpoison ){ 01000 hp++; 01001 sp++; 01002 } 01003 01004 delay_alcohol = QueryProp(P_ALCOHOL_DELAY); 01005 } 01006 01007 if ( (--delay_drink < 0) && !(rlock & NO_REG_DRINK) ){ 01008 delay_drink = QueryProp(P_DRINK_DELAY); 01009 SetProp( P_DRINK, QueryProp(P_DRINK) - 1 ); 01010 } 01011 01012 if ( (--delay_food < 0) && !(rlock & NO_REG_FOOD) ){ 01013 delay_food = QueryProp(P_FOOD_DELAY); 01014 SetProp( P_FOOD, QueryProp(P_FOOD) - 1 ); 01015 } 01016 01017 /* normal regeneration */ 01018 if ( hp_buffer[0] && !(rlock & NO_REG_BUFFER_HP) ){ 01019 rate = hp_buffer[1]; 01020 val = hp_buffer[rate + 1]; 01021 01022 if ( val > rate ) 01023 val = rate; 01024 01025 hp_buffer[0] -= val; 01026 hp_buffer[rate + 1] -= val; 01027 hp += val; 01028 01029 if ( hp_buffer[rate + 1] <= 0 ) 01030 update_buffers(); 01031 } 01032 else if ( (--delay_heal < 0) && !(rlock & NO_REG_HP) ){ 01033 delay_heal = QueryProp(P_HP_DELAY); 01034 01035 if ( !hpoison ) 01036 hp++; 01037 } 01038 01039 if ( sp_buffer[0] && !(rlock & NO_REG_BUFFER_SP) ){ 01040 rate = sp_buffer[1]; 01041 val = sp_buffer[rate + 1]; 01042 01043 if ( val > rate ) 01044 val = rate; 01045 01046 sp_buffer[0] -= val; 01047 sp_buffer[rate + 1] -= val; 01048 sp += val; 01049 01050 if ( sp_buffer[rate + 1] <= 0 ) 01051 update_buffers(); 01052 } 01053 else if ( (--delay_sp < 0) && !(rlock & NO_REG_SP) ){ 01054 delay_sp = QueryProp(P_SP_DELAY); 01055 01056 if ( !hpoison ) 01057 sp++; 01058 } 01059 01060 if ( hpoison && (interactive(ME) || !query_once_interactive(ME)) ){ 01061 // Vanion, 26.10.03 01062 // Wenn _set_poison() per SET_METHOD ueberschrieben wird, kann 01063 // nicht sichergestellt werden, dass poison immer groesser 0 ist 01064 // Daher muss hier ein Test rein, so teuer das auch ist :( 01065 if (--hpoison < 0) hpoison=0; 01066 01067 if ( --delay_poison < 0 ){ 01068 delay_poison = QueryProp(P_POISON_DELAY) 01069 + random(POISON_MERCY_DELAY); 01070 hp -= hpoison; 01071 01072 if ( hp < 0 ){ 01073 tell_object( ME, "Oh weh - das Gift war zuviel fuer Dich!\n" 01074 + "Du stirbst.\n" ); 01075 01076 if ( query_once_interactive(ME) ){ 01077 create_kill_log_entry( "Vergiftung", 0 ); 01078 01079 // Beim Gifttod gibt es keinen Killer. Aber auf diese Art 01080 // erkennt der Todesraum die Ursache korrekt und gibt die 01081 // richtige Meldung aus. 01082 SetProp( P_KILLER, "gift" ); 01083 } 01084 01085 die(1); 01086 return; 01087 } 01088 01089 if ( (hpoison < 3 || !query_once_interactive(ME) ) 01090 && --drop_poison < 0){ 01091 switch (hpoison) { 01092 case 1: 01093 drop_poison += 15 + random(6); // Das werden etwa 50... 01094 01095 case 2: 01096 drop_poison += 25 + random(10); 01097 01098 case 0: 01099 Set( P_POISON, hpoison ); 01100 if ( !hpoison ) 01101 tell_object( ME, "Du scheinst die Vergiftung " 01102 "ueberwunden zu haben.\n" ); 01103 break; 01104 01105 default: 01106 drop_poison += (20 - 2*hpoison + random(40 - 3*hpoison)); 01107 Set( P_POISON, hpoison ); 01108 } 01109 } 01110 } 01111 01112 if ( hpoison && !random(15) ) 01113 switch ( hp*100/QueryProp(P_MAX_HP) ){ 01114 case 71..100 : 01115 write( "Du fuehlst Dich nicht gut.\n" ); 01116 say( capitalize(name(WER)) + 01117 " sieht etwas benommen aus.\n" ); 01118 break; 01119 01120 case 46..70 : 01121 write( "Dir ist schwindlig und Dein Magen revoltiert.\n" ); 01122 say( capitalize(name(WER)) + " taumelt ein wenig.\n" ); 01123 break; 01124 01125 case 26..45 : 01126 write( "Dir ist heiss. Du fuehlst Dich schwach. Kopfweh " 01127 "hast Du auch.\n" ); 01128 say( capitalize(name(WER)) + " glueht direkt und scheint " 01129 "grosse Schwierigkeiten zu haben.\n" ); 01130 break; 01131 01132 case 11..25 : 01133 write( "Du fuehlst Dich beschissen. Alles tut weh, und Du " 01134 "siehst nur noch unscharf.\n" ); 01135 say( capitalize(name(WER)) + " taumelt und stoehnt und " 01136 "kann gerade noch vermeiden, hinzufallen.\n" ); 01137 break; 01138 01139 case 0..10 : 01140 write( break_string( "Du siehst fast nichts mehr und kannst " 01141 "Dich nur noch unter groessten Schmerzen " 01142 "bewegen. Aber bald tut nichts mehr weh" 01143 "...", 78 ) ); 01144 say( break_string( capitalize(name(WER)) + " glueht wie " 01145 "im Fieber, kann sich kaum noch ruehren " 01146 "und hat ein schmerzverzerrtes Gesicht.\n", 01147 78 ) ); 01148 break; 01149 } 01150 } 01151 01152 SetProp( P_HP, hp ); 01153 SetProp( P_SP, sp ); 01154 }

| public int reduce_hit_points | ( | int | dam | ) |
Definiert in Zeile 740 der Datei life.c.
Benutzt i, log_file, ME, name, P_HP, QueryProp(), SetProp() und WER.
Wird benutzt von restore_hit_points().
00741 { object o; 00742 int i; 00743 00744 #ifdef LOG_REDUCE_HP 00745 if (this_player()!=ME) 00746 { 00747 log_file("REDUCE_HP", name()+" by "); 00748 if(!this_player()) log_file("REDUCE_HP","?\n"); 00749 else { 00750 log_file("REDUCE_HP",this_player()->name()); 00751 o=previous_object(); 00752 if (o) 00753 log_file("REDUCE_HP", " " + object_name(o) + ", " + 00754 o->name(WER,0) + " (" + creator(o) + ")\n"); 00755 else 00756 log_file("REDUCE_HP", " ??\n"); 00757 } 00758 } 00759 #endif 00760 if ((i=QueryProp(P_HP)) <= dam) 00761 return SetProp(P_HP,1); 00762 return SetProp(P_HP, i - dam); 00763 }


| public void reduce_spell_points | ( | int | h | ) |
| public int restore_hit_points | ( | int | heal | ) |
Definiert in Zeile 765 der Datei life.c.
Benutzt reduce_hit_points().
00766 { 00767 return reduce_hit_points(-heal); 00768 }

| public void restore_spell_points | ( | int | h | ) |
| varargs protected int second_life | ( | object | corpse | ) |
| public void show_age | ( | ) |
Definiert in Zeile 1157 der Datei life.c.
Benutzt i, P_AGE und QueryProp().
Wird benutzt von score().
01158 { int i,j; 01159 01160 write("Alter:\t"); 01161 i = QueryProp(P_AGE); 01162 if ((j=i/43200)) 01163 { 01164 write(j + " Tag"+(j==1?" ":"e ")); 01165 i %= 43200; 01166 } 01167 if ((j=i/1800)) 01168 { 01169 write(j + " Stunde"+(j==1?" ":"n ")); 01170 i %= 1800; 01171 } 01172 if ((j=i/30)) 01173 { 01174 write(j + " Minute"+(j==1?" ":"n ")); 01175 i %= 30; 01176 } 01177 write(i*2 + " Sekunden.\n"); 01178 }


| public varargs void transfer_all_to | ( | mixed | dest, | |
| int | isnpc | |||
| ) |
Definiert in Zeile 311 der Datei life.c.
00311 { 00312 int flags; 00313 object *obs; 00314 00315 if ( !objectp(ME) ) 00316 return; 00317 00318 // Das Flag "isnpc" ist fuer NPCs gedacht. Deren Ausruestung darf nicht 00319 // mit M_NOCHECK bewegt werden, da Spieler das bei Nicht-Standard-Leichen 00320 // sonst u.U. ausnutzen koennten. 00321 if ( isnpc ) 00322 flags = M_SILENT; 00323 else 00324 flags = M_SILENT|M_NOCHECK; 00325 00326 obs = all_inventory(ME) || ({}); 00327 00328 // unnoetig, weil _transfer() auch auf P_NEVERDROP prueft. Zesstra 00329 //obs -= filter_objects( obs, "QueryProp", P_NEVERDROP ); 00330 00331 _transfer( obs, dest, flags ); 00332 }
| protected void update_buffers | ( | ) |
Definiert in Zeile 867 der Datei life.c.
Benutzt hp_buffer, i, m_delete() und sp_buffer.
Wird benutzt von heart_beat().
00868 { int i, rate, max; 00869 00870 rate=0; 00871 max=0; 00872 for(i=1;i<=20;i++){ 00873 if(member(hp_buffer, i+1)) 00874 if(hp_buffer[i+1]<=0) 00875 hp_buffer = efun::m_delete(hp_buffer,i+1); 00876 else{ 00877 max+=hp_buffer[i+1]; 00878 rate=i; 00879 } 00880 } 00881 00882 hp_buffer[0]=max; 00883 hp_buffer[1]=rate; 00884 rate=0; 00885 max=0; 00886 for(i=1;i<=20;i++){ 00887 if(member(sp_buffer, i+1)) 00888 if(sp_buffer[i+1]<=0) 00889 sp_buffer = efun::m_delete(sp_buffer,i+1); 00890 else{ 00891 max+=sp_buffer[i+1]; 00892 rate=i; 00893 } 00894 } 00895 sp_buffer[0]=max; 00896 sp_buffer[1]=rate; 00897 }


| nosave int delay_alcohol |
Definiert in Zeile 58 der Datei life.c.
Wird benutzt von heart_beat().
| nosave int delay_drink |
Definiert in Zeile 59 der Datei life.c.
Wird benutzt von heart_beat().
| nosave int delay_food |
Definiert in Zeile 60 der Datei life.c.
Wird benutzt von heart_beat().
| nosave int delay_heal |
Definiert in Zeile 61 der Datei life.c.
Wird benutzt von heart_beat().
| nosave int delay_poison |
Definiert in Zeile 63 der Datei life.c.
Wird benutzt von heart_beat().
| nosave int delay_sp |
Definiert in Zeile 62 der Datei life.c.
Wird benutzt von heart_beat().
| nosave int drop_poison |
Definiert in Zeile 64 der Datei life.c.
Wird benutzt von _set_poison() und heart_beat().
| nosave mapping enemy_damage |
Definiert in Zeile 65 der Datei life.c.
Wird benutzt von _query_enemy_damage(), create(), DistributeExp() und do_damage().
| nosave mapping hp_buffer |
Definiert in Zeile 66 der Datei life.c.
Wird benutzt von buffer_hp(), create(), heart_beat() und update_buffers().
Definiert in Zeile 70 der Datei life.c.
Wird benutzt von create() und defuel_drink().
Definiert in Zeile 69 der Datei life.c.
Wird benutzt von create() und defuel_food().
| nosave mapping sp_buffer |
Definiert in Zeile 67 der Datei life.c.
Wird benutzt von buffer_sp(), create(), heart_beat() und update_buffers().
1.6.3