life.c-Dateireferenz

#include <rtlimits.h>
#include <debug_info.h>
#include <thing/properties.h>
#include <player/base.h>
#include <moving.h>
#include <config.h>
#include <wizlevels.h>
#include <defines.h>
#include <language.h>
#include <hook.h>
#include <player/pklog.h>
#include <player/combat.h>
#include <health.h>
#include <living/combat.h>
#include <attributes.h>
#include <defuel.h>
#include <new_skills.h>
Include-Abhängigkeitsdiagramm für life.c:

gehe zum Quellcode dieser Datei

Makrodefinitionen

#define NEED_PROTOTYPES
#define SUFFER_TIME   7200
#define P_DEATH_INFO   "death_info"

Funktionen

static int _set_playerkills (int val)
protected void create ()
protected void reconnect ()
public int death_suffering ()
protected void heart_beat ()
public void force_save ()
nomask public int do_damage (int dam, object enemy)
private void reset_my_properties ()
varargs protected int second_life (object corpse)
public int AddHpHook (object ob)
public int RemoveHpHook (object ob)
static int _set_hp (int hp)
static int _set_sp (int sp)
static int _set_ghost (int g)
public int undie ()
varargs public void die (int poisondeath, int extern)
int defuel_food ()
int defuel_drink ()

Variablen

inherit std living life
private int suffer_time
static int time_to_save
private nosave int die_in_progress

Makro-Dokumentation

#define NEED_PROTOTYPES

Definiert in Zeile 20 der Datei life.c.

#define P_DEATH_INFO   "death_info"

Definiert in Zeile 43 der Datei life.c.

Wird benutzt von create().

#define SUFFER_TIME   7200

Definiert in Zeile 42 der Datei life.c.


Dokumentation der Funktionen

static int _set_ghost ( int  g  )  [static]

Definiert in Zeile 515 der Datei life.c.

00515                                {
00516     object team;
00517 
00518     if(!g && query_hc_play()>1)
00519     {
00520       write("HAHAHA, DU BIST AUF EWIG MEIN.\n");
00521       return Query(P_GHOST);
00522     }
00523 
00524     g = Set( P_GHOST, g );
00525 
00526     if ( g && objectp(team = Query(P_TEAM)) )
00527         team->RemoveMember(ME);
00528 
00529     return g;
00530 }

static int _set_hp ( int  hp  )  [static]

Definiert in Zeile 468 der Datei life.c.

00469 {
00470     object *hooks;
00471     int ret, i, old;
00472 
00473     if ( (old = Query(P_HP)) == hp )
00474         return old;
00475 
00476     ret = life::_set_hp(hp);
00477 
00478     if ( ret == old )
00479         return hp;
00480 
00481     // Call old hooks in all objects... destructed objects will be ignored.
00482     if (pointerp(hooks = Query(P_HP_HOOKS)))
00483       call_other(hooks, "NotifyHpChange");
00484 
00485     // Call new hooks.
00486     HookFlow(H_HOOK_HP,ret);
00487 
00488     return ret;
00489 }

static int _set_playerkills ( int  val  )  [static]

Definiert in Zeile 78 der Datei life.c.

00079 {
00080     string tmp;
00081     int playerkills;
00082 
00083     // ist der Setzer in einer Arena/Schattenwelt. Dann nicht. (Ja, Bug ist,
00084     // dass EMs aus Schattenwelt/Arena heraus auch das PK-Flag nicht
00085     // zuruecksetzen koennen.)
00086     if ( previous_object(1) && environment(previous_object(1)) &&
00087          (tmp = object_name(environment(previous_object(1)))) &&
00088                  CheckArenaFight(previous_object(1)) )
00089         return 0;
00090 
00091     tmp = sprintf( "%O: %s %O %s",
00092                    previous_object(1) || this_interactive() || this_player(),
00093                    getuid(ME), val, dtime(time()) );
00094 
00095     playerkills = Query(P_KILLS);
00096 
00097     if( intp(val) && val >= 0 )
00098         if( previous_object(1) && IS_ARCH(getuid(previous_object(1))) &&
00099             this_interactive() && IS_ARCH(this_interactive()) )
00100             playerkills = val;
00101         else
00102             tmp += " ILLEGAL!";
00103     else
00104         playerkills++;
00105 
00106     if ( !previous_object(1) || !query_once_interactive(previous_object(1)) ||
00107          IS_LEARNER(previous_object(1)) )
00108         log_file( "SET_KILLS", tmp + "\n" );
00109 
00110     return Set( P_KILLS, playerkills );
00111 }

static int _set_sp ( int  sp  )  [static]

Definiert in Zeile 492 der Datei life.c.

00493 {
00494     object *hooks;
00495     int ret, i, old;
00496 
00497     if ( (old = Query(P_SP)) == sp )
00498         return old;
00499 
00500     ret = life::_set_sp(sp);
00501 
00502     if ( ret == old )
00503         return sp;
00504 
00505     // Call old hooks in all objects... destructed objects will be ignored.
00506     if (pointerp(hooks = Query(P_HP_HOOKS)))
00507       call_other(hooks, "NotifyHpChange");
00508 
00509     // Call new hooks.
00510    HookFlow(H_HOOK_SP,ret);
00511 
00512     return ret;
00513 }

public int AddHpHook ( object  ob  ) 

Definiert in Zeile 436 der Datei life.c.

00437 {
00438     object *hooks;
00439 
00440     if ( !objectp(ob) )
00441         return 0;
00442 
00443     if ( !pointerp(hooks = Query(P_HP_HOOKS)) ){
00444         Set( P_HP_HOOKS, ({ ob }) );
00445         return 1;
00446     }
00447 
00448     if ( member( hooks, ob ) >= 0 )
00449         return 0;
00450 
00451     Set( P_HP_HOOKS, (hooks - ({0})) + ({ ob }) );
00452     return 1;
00453 }

protected void create (  ) 

Definiert in Zeile 52 der Datei life.c.

Benutzt call_out(), create(), F_MODE_AS, H_HOOK_HP, H_HOOK_SP, offerHook(), P_DEATH_INFO, 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_GHOST, P_KILLS, P_LAST_DEATH_TIME, P_TIMING_MAP, PROTECTED, SAVE, SECURED und Set().

00053 {
00054     ::create();
00055     Set( P_KILLS, SAVE|SECURED, F_MODE_AS );
00056     Set( P_GHOST, SAVE, F_MODE_AS );
00057     Set( P_TIMING_MAP, SAVE|SECURED, F_MODE_AS );
00058     Set( P_LAST_DEATH_TIME, SAVE|SECURED, F_MODE_AS );
00059     Set( P_DEATH_INFO, SAVE|SECURED, F_MODE_AS );
00060     Set( P_DEFUEL_LIMIT_FOOD,PROTECTED,F_MODE_AS);
00061     Set( P_DEFUEL_LIMIT_DRINK,PROTECTED,F_MODE_AS);
00062     Set( P_DEFUEL_TIME_FOOD,PROTECTED,F_MODE_AS);
00063     Set( P_DEFUEL_TIME_DRINK,PROTECTED,F_MODE_AS);
00064     Set( P_DEFUEL_AMOUNT_FOOD,PROTECTED,F_MODE_AS);
00065     Set( P_DEFUEL_AMOUNT_DRINK,PROTECTED,F_MODE_AS);
00066     offerHook(H_HOOK_HP,1);
00067     offerHook(H_HOOK_SP,1);
00068     // P_TIMING_MAP aufraeumen, aber zeitverzoegert, weil jetzt die Daten noch
00069     // nicht aus dem Savefile geladen wurden.
00070     call_out(#'expire_timing_map, 4);
00071 }

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

public int death_suffering (  ) 

Definiert in Zeile 114 der Datei life.c.

00115 {
00116     if ( suffer_time <= 0 )
00117     return suffer_time = 0;
00118 
00119     return 1 + (10 * suffer_time) / SUFFER_TIME;
00120 }

int defuel_drink (  ) 

Definiert in Zeile 713 der Datei life.c.

Benutzt defuel_drink() und FUELSTAT.

00714 {
00715     int ret;
00716     object prev;
00717     
00718     ret=::defuel_drink();
00719     prev=previous_object();
00720     if(!prev || !objectp(prev))
00721     {
00722         prev=this_object();
00723     }
00724     
00725     if(ret<=0)
00726     {
00727                 call_other(FUELSTAT,"addDefuelStatEntry",prev,this_object(),0,1,0,0);
00728     }
00729     else
00730     {
00731                 call_other(FUELSTAT,"addDefuelStatEntry",prev,this_object(),0,0,ret,0);
00732     }
00733     return ret;
00734 }

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

int defuel_food (  ) 

Definiert in Zeile 690 der Datei life.c.

Benutzt defuel_food() und FUELSTAT.

00691 {
00692     int ret;
00693     object prev;
00694     
00695     ret=::defuel_food();
00696     prev=previous_object();
00697     if(!prev || !objectp(prev))
00698     {
00699         prev=this_object();
00700     }
00701     
00702     if(ret<=0)
00703     {
00704                 call_other(FUELSTAT,"addDefuelStatEntry",prev,this_object(),0,1,0,1);
00705     }
00706     else
00707     {
00708                 call_other(FUELSTAT,"addDefuelStatEntry",prev,this_object(),0,0,ret,1);
00709     }
00710     return ret;
00711 }

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

varargs public void die ( int  poisondeath,
int  extern 
)

Definiert in Zeile 615 der Datei life.c.

00616 {
00617     // laeuft schon ein die()? Fehler ausloesen, Ursache rekursiver die() soll
00618     // gefunden werden. DINFO_EVAL_NUMBER wird in jedem Top-Level Call im
00619     // driver erhoeht, d.h. gleiche Zahl signalisiert ein rekursives die().
00620 #ifdef DINFO_EVAL_NUMBER
00621     if (die_in_progress == debug_info(DINFO_EVAL_NUMBER))
00622 #else
00623     if (die_in_progress == time()) {
00624 #endif
00625       // TODO: ist das die_in_progress aus dem letzten Backend-Cycle?
00626       raise_error(sprintf(
00627             "die() in %O gerufen, aber die() laeuft bereits!\n",
00628             this_object()));
00629     }
00630 #ifdef DINFO_EVAL_NUMBER
00631     die_in_progress = debug_info(DINFO_EVAL_NUMBER);
00632 #else
00633     die_in_progress = time();
00634 #endif
00635 
00636     // Fuer HC-Player ists jetzt gelaufen...
00637     if(query_hc_play()==1)
00638     {
00639       set_hc_play(capitalize(geteuid(ME)),time());
00640       SetDefaultHome("/room/nirvana");
00641       SetPrayRoom("/room/nirvana");
00642       SetProp(P_START_HOME,"/room/nirvana");
00643       log_file("HCDEAD",dtime(time())+" "+capitalize(geteuid(ME))
00644           +" geht in das Nirvana ein!\n");
00645     }
00646 
00647     // Wenn das die() direkt von aussen gerufen wurde, muss P_KILLER hier
00648     // gespeichert werden.
00649     if (extern_call())
00650         SetProp(P_KILLER, previous_object());
00651 
00652     // Sichern der zu loeschenden Properties. Diese Props werden im Verlauf des
00653     // Todes zurueckgesetzt. Einige Magier wollen diese Daten aber spaeter
00654     // noch haben und fragen teilweise P_LAST_DEATH_PROPS im
00655     // NotifyPlayerDeath() ab. Daher wird der Kram jetzt hier schonmal
00656     // gesichert.
00657     // BTW: Props mit Mappings/Arrays sollten kopiert werden.
00658     SetProp(P_LAST_DEATH_PROPS, ([
00659       P_POISON          : QueryProp(P_POISON),
00660       P_FROG            : QueryProp(P_FROG),
00661       P_ALCOHOL         : QueryProp(P_ALCOHOL),
00662       P_DRINK           : QueryProp(P_DRINK),
00663       P_FOOD            : QueryProp(P_FOOD),
00664       P_BLIND           : QueryProp(P_BLIND),
00665       P_DEAF            : QueryProp(P_DEAF),
00666       P_MAX_HANDS       : QueryProp(P_MAX_HANDS),
00667       P_PARA            : QueryProp(P_PARA),
00668       P_NO_REGENERATION : QueryProp(P_NO_REGENERATION),
00669       P_HP              : QueryProp(P_HP),
00670       P_SP              : QueryProp(P_SP),
00671       P_LAST_DEATH_TIME : QueryProp(P_LAST_DEATH_TIME )
00672     ]) );
00673 
00674     // call the inherited die() with 10 Mio Ticks which will be accounted as 1
00675     // Tick... ;-)
00676     int *limits = query_limits();
00677     limits[LIMIT_EVAL] == 10000000;
00678     limits[LIMIT_COST] == LIMIT_UNLIMITED;
00679     limited(#'::die, limits, poisondeath, (extern_call() ? 1 : 0)); 
00680 
00681     // nach dem Tod sollte man auch keine LP mehr haben.
00682     SetProp(P_HP, 0);
00683 
00684     // naechster Tod kann kommen. Dekrementierung, da 0 ein gueltiger Wert
00685     // fuer DINFO_EVAL_NUMBER waere. abs(), um nicht  -__INT_MAX__ zu
00686     // dekrementieren.
00687     die_in_progress = abs(die_in_progress) - 1;
00688 }

nomask public int do_damage ( int  dam,
object  enemy 
)

Definiert in Zeile 212 der Datei life.c.

00213 {
00214     int hit_point;
00215 
00216     if( QueryProp(P_GHOST) || dam <= 0 )
00217         return 0;
00218 
00219     hit_point = QueryProp(P_HP);
00220 
00221     if ( query_once_interactive(ME) && dam >= hit_point && IS_LEARNING(ME) ){
00222         tell_object( ME, "Deine magischen Kraefte verhindern Deinen Tod.\n" );
00223         return 0;
00224     }
00225 
00226     if ( !objectp(enemy) )
00227         enemy = previous_object() || this_interactive() || this_player();
00228 
00229     hit_point -= dam;
00230 
00231     if( hit_point < 0 ){
00232         if ( !interactive(ME) )
00233             // Netztote sterben nicht
00234             hit_point = 10;
00235         else {
00236             if ( objectp(enemy) && interactive( enemy ) && enemy != ME &&
00237                  !QueryProp(P_TESTPLAYER) && !IS_WIZARD(ME) &&
00238                  !CheckArenaFight(ME) ) {
00239                 if ( QueryPlAttacked(enemy) )
00240                     hit_point = 1;
00241                 else {
00242                     hit_point = 0;
00243                     enemy->SetProp( P_KILLS, -1 );
00244                 }
00245 
00246                 log_file( "KILLER",
00247                           sprintf( "%s %s(%d/%d) toetete %s(%d/%d)%s\n",
00248                                    ctime(time()),
00249                                    getuid(enemy), query_wiz_level(enemy),
00250                                    (int) enemy->QueryProp(P_LEVEL), getuid(ME),
00251                                    query_wiz_level(ME), QueryProp(P_LEVEL),
00252                                    (hit_point ? " NOTWEHR=>KEIN PK" : "") ) );
00253             }
00254             else { 
00255                 string killername;
00256                 if (objectp(enemy))
00257                     killername=sprintf("%s (%s)",
00258                         BLUE_NAME(enemy), REAL_UID(enemy));
00259                 else
00260                     killername="??? (???)"; 
00261 
00262                 if ( !QueryProp(P_TESTPLAYER) )
00263                     create_kill_log_entry(killername, enemy );
00264             }
00265 
00266             if ( enemy )
00267                 enemy->StopHuntFor( ME, 1 );
00268 
00269             map_objects( QueryEnemies()[0], "StopHuntFor", ME, 1 );
00270             StopHuntingMode(1);
00271 
00272             Set( P_KILLER, enemy );
00273             die();
00274         }
00275     }
00276 
00277     SetProp( P_HP, hit_point );
00278     return dam;
00279 }

public void force_save (  ) 

Definiert in Zeile 207 der Datei life.c.

Wird benutzt von AddScore(), ClearScoreBit(), DeleteQuest(), GiveQuest() und SetScoreBit().

00207                          {
00208     time_to_save = 0;
00209 }

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

protected void heart_beat (  ) 

Definiert in Zeile 123 der Datei life.c.

00124 {
00125     mapping di, mods;
00126 
00127     ::heart_beat();
00128 
00129     if ( age > time_to_save ){
00130         save_me(1);
00131         time_to_save = age + 500;
00132     }
00133 
00134     // als geist hat man mit den meisten weltlichen Dingen nicht allzuviel zu
00135     // tun.
00136     if ( QueryProp(P_GHOST) )
00137         return;
00138 
00139     if ( suffer_time > 0 )
00140         suffer_time--;
00141 
00142     // Todesfolgen nur alle 20 Sekunden (10 HB) checken.
00143     // Das ist immer noch oft genug und spart Rechenzeit.
00144     if ( (age % 10) || !mappingp(di = QueryProp(P_DEATH_INFO)) )
00145         return;
00146 
00147     mods = QueryProp(P_ATTRIBUTES_MODIFIER)["#death"];
00148     if (!mappingp(mods)) return;
00149 
00150     if ( mods[A_STR] && --di[A_STR] <= 0) {
00151                 // einen Attributspunkt regenerieren
00152         if ( mods[A_STR] < -1 ) {
00153             mods[A_STR]++;
00154             di[A_STR] = (110 + 5 * (di[A_STR, 1] + mods[A_STR])) / 10;
00155         }
00156         else {
00157             efun::m_delete( mods, A_STR );
00158             efun::m_delete( di, A_STR );
00159         }
00160     }
00161 
00162     if ( mods[A_CON] && --di[A_CON] <= 0) {
00163                 // einen Attributspunkt regenerieren
00164         if ( mods[A_CON] < -1 ){
00165             mods[A_CON]++;
00166             di[A_CON] = (110 + 5 * (di[A_CON, 1] + mods[A_CON])) / 10;
00167         }
00168         else {
00169             efun::m_delete( mods, A_CON );
00170             efun::m_delete( di, A_CON );
00171         }
00172     }
00173 
00174     if ( mods[A_DEX] && --di[A_DEX] <= 0) {
00175                 // einen Attributspunkt regenerieren
00176         if ( mods[A_DEX] < -1 ){
00177             mods[A_DEX]++;
00178             di[A_DEX] = (110 + 5 * (di[A_DEX, 1] + mods[A_DEX])) / 10;
00179         }
00180         else {
00181             efun::m_delete( mods, A_DEX );
00182             efun::m_delete( di, A_DEX );
00183         }
00184     }
00185 
00186     if ( mods[A_INT] && --di[A_INT] <= 0) {
00187                 // einen Attributspunkt regenerieren
00188         if ( mods[A_INT] < -1 ){
00189             mods[A_INT]++;
00190             di[A_INT] = (110 + 5 * (di[A_INT, 1] + mods[A_INT])) / 10;
00191         }
00192         else {
00193             efun::m_delete( mods, A_INT );
00194             efun::m_delete( di, A_INT );
00195         }
00196     }
00197 
00198     if ( sizeof(di) && sizeof(mods))
00199         SetProp( P_DEATH_INFO, di );
00200     else
00201         SetProp( P_DEATH_INFO, 0 );
00202 
00203     SetProp( P_ATTRIBUTES_MODIFIER, ({ "#death", mods }) );
00204 }

protected void reconnect (  ) 

Definiert in Zeile 74 der Datei life.c.

00074                            {
00075   expire_timing_map();
00076 }

public int RemoveHpHook ( object  ob  ) 

Definiert in Zeile 456 der Datei life.c.

00457 {
00458     object *hooks;
00459 
00460     if ( !pointerp(hooks = Query(P_HP_HOOKS)) )
00461         return 0;
00462 
00463     Set( P_HP_HOOKS, hooks - ({ ob, 0 }) );
00464     return 1;
00465 }

private void reset_my_properties (  ) 

Definiert in Zeile 284 der Datei life.c.

00285 {
00286   // Loeschen der Properties
00287   if ( QueryProp(P_POISON) )
00288   {
00289      Set( P_POISON, 0, F_SET_METHOD );
00290      Set( P_POISON, 0, F_QUERY_METHOD );
00291      Set( P_POISON, 0 ); /* Don't die twice 'cause of the same poison */
00292   }
00293 
00294   Set( P_FROG, 0, F_QUERY_METHOD ); 
00295   SetProp( P_FROG, 0 ); // Damit die Attribute auch stimmen.
00296   Set( P_ALCOHOL, 0, F_VALUE );
00297   Set( P_ALCOHOL, 0, F_QUERY_METHOD );
00298   Set( P_DRINK, 0, F_VALUE );
00299   Set( P_DRINK, 0, F_QUERY_METHOD );
00300   Set( P_FOOD, 0, F_VALUE );
00301   Set( P_FOOD, 0, F_QUERY_METHOD );
00302   Set( P_BLIND, 0, F_VALUE );
00303   Set( P_BLIND, 0, F_QUERY_METHOD );
00304   Set( P_DEAF, 0, F_VALUE );
00305   Set( P_DEAF, 0, F_QUERY_METHOD );
00306   Set( P_MAX_HANDS, 2, F_VALUE );
00307   Set( P_MAX_HANDS, 0, F_QUERY_METHOD );
00308   Set( P_HANDS_USED_BY, 0, F_QUERY_METHOD );
00309   Set( P_HANDS_USED_BY, ({}), F_VALUE );
00310   Set( P_PARA, 0 );
00311   Set( P_NO_REGENERATION, 0 );
00312   Set( P_NO_REGENERATION, 0, F_QUERY_METHOD );
00313   // damit der Teddy o.ae. mitbekommt, dass man jetzt tot ist ]:->
00314   SetProp( P_HP, 0 );
00315   SetProp( P_SP, 0 );
00316   Set( P_LAST_DEATH_TIME , time() );
00317 
00318   Set( P_TMP_MOVE_HOOK, 0, F_QUERY_METHOD );
00319   Set( P_TMP_MOVE_HOOK, 0, F_VALUE );
00320 }

varargs protected int second_life ( object  corpse  ) 

Definiert in Zeile 322 der Datei life.c.

00323 {
00324     int lost_exp, level;
00325     // Es gibt Funktionen, die sollte man nicht per Hand aufrufen duerfen ;-)
00326     if ( extern_call() && previous_object() != ME )
00327         return 0;
00328 
00329     if ( query_once_interactive(ME) && IS_LEARNING(ME) ){
00330         tell_object( ME, "Sei froh, dass Du unsterblich bist, sonst waere "
00331                      "es eben zu Ende gewesen.\n" );
00332         return 1;
00333     }
00334 
00335     SetProp( P_GHOST, 1 );
00336 
00337     if ( !IS_SEER(ME) || (level = QueryProp(P_LEVEL)) < 20 )
00338         lost_exp = QueryProp(P_XP) / 3;
00339     else
00340         lost_exp = QueryProp(P_XP) / (level - 17);
00341 
00342     AddExp(-lost_exp);
00343 
00344 
00345     // Todesfolgen setzen....
00346     //SetProp( P_DEATH_INFO, 1);
00347     if ( !IS_LEARNING(ME) && !QueryProp(P_TESTPLAYER) ) {
00348 
00349         mapping attr = QueryProp(P_ATTRIBUTES);
00350         mapping mods = QueryProp(P_ATTRIBUTES_MODIFIER)["#death"] || ([]);
00351 
00352         // Attribute auf 75% vom aktuellen Wert senken
00353         mods[A_STR] = -attr[A_STR] + (3 * (attr[A_STR] + mods[A_STR]) / 4);
00354         mods[A_CON] = -attr[A_CON] + (3 * (attr[A_CON] + mods[A_CON]) / 4);
00355         mods[A_DEX] = -attr[A_DEX] + (3 * (attr[A_DEX] + mods[A_DEX]) / 4);
00356         mods[A_INT] = -attr[A_INT] + (3 * (attr[A_INT] + mods[A_INT]) / 4);
00357 
00358         SetProp( P_ATTRIBUTES_MODIFIER, ({ "#death", mods }) );
00359 
00360         int offs = 220;  // 220 heart_beats == 7min20
00361         // Die 220 HB sind fix, dazu kommen noch 5 HB pro realem 
00362         // Attributspunkt. Geteilt wird das ganze noch durch 10, weil im HB
00363         // nur alle 10 HBs die TF gecheckt werden. Da wird dann alle 10 HB ein
00364         // Punkt abgezogen und wenn 0 erreicht ist, wird das Attribut um eins
00365         // regeneriert.
00366         SetProp( P_DEATH_INFO, ([ 
00367             A_STR: (offs + 5 * (attr[A_STR] + mods[A_STR]))/10; attr[A_STR],
00368             A_CON: (offs + 5 * (attr[A_CON] + mods[A_CON]))/10; attr[A_CON],
00369             A_DEX: (offs + 5 * (attr[A_DEX] + mods[A_DEX]))/10; attr[A_DEX],
00370             A_INT: (offs + 5 * (attr[A_INT] + mods[A_INT]))/10; attr[A_INT]
00371                   ]) );
00372 
00373         // die suffer_time wird via death_suffering() von
00374         // QuerySkillAttribute() abgefragt und geht dann als Malus in
00375         // SA_QUALITY mit ein.
00376         if ( suffer_time < 2*SUFFER_TIME )
00377             suffer_time += (SUFFER_TIME)-1;
00378     }
00379 
00380     object env = environment();
00381 
00382     clone_object( "room/death/death_mark" )->move( ME, M_NOCHECK );
00383 
00384     // Die verschiedenen NotifyPlayerDeath-Funktionen koennen u.U. schlecht
00385     // programmiert sein und zuviel Rechenzeit ziehen. Deshalb werden sie mit
00386     // einem Limits von 150k bzw. 80k aufgerufen. Ausserdem werden sie nur
00387     // gerufen, solange noch min. 25k Ticks da sind.
00388     int *limits=query_limits();
00389     limits[LIMIT_EVAL] = 150000;
00390     limits[LIMIT_COST] = LIMIT_DEFAULT;
00391 
00392     mixed killer = QueryProp(P_KILLER);
00393     mixed gi = QueryProp(P_GUILD);
00394     if (stringp(gi))
00395         gi = find_object("/gilden/"+gi);
00396     // jedes Objekt nur einmal, aber nicht via m_indices(mkmapping)) wegen
00397     // Verlust der Reihenfolge.
00398     object *items = ({killer});
00399     if (env != killer)
00400         items += ({env});
00401     if (gi != killer && gi != env)
00402         items += ({gi});
00403     foreach(object item: items) {
00404         if (get_eval_cost() < limits[LIMIT_EVAL] + 20000)
00405             break;
00406         // falls ein NPD() implizit andere Objekt zerstoert hat.
00407         if (objectp(item)) {
00408             catch(limited(#'call_other, limits, item, "NotifyPlayerDeath",
00409                   ME, killer, lost_exp);publish);
00410         }
00411     }
00412     // jetzt den Rest.
00413     limits[LIMIT_EVAL] = 80000;
00414     foreach(object item: (env ? all_inventory(env) : ({}))
00415                         + deep_inventory(ME)
00416                         + (objectp(corpse) ? deep_inventory(corpse) : ({}))
00417                         - items ) {
00418         // wenn nicht mehr genug Ticks, haben die restlichen Pech gehabt.
00419         if (get_eval_cost() < limits[LIMIT_EVAL] + 20000)
00420             break;
00421         // NPD() koennen andere Objekt zerstoeren.
00422         if (objectp(item)) {
00423             catch(limited(#'call_other, limits, item, "NotifyPlayerDeath",
00424                                     ME, killer, lost_exp);publish);
00425         }
00426     }
00427 
00428     // Properties zuruecksetzen
00429     reset_my_properties();
00430     UpdateAttributes(); // Beim Tod werden Dinge entfernt, Attribute pruefen
00431 
00432     return 1;
00433 }

public int undie (  ) 

Definiert in Zeile 532 der Datei life.c.

00533 {
00534     mixed x, di;
00535     mapping attr, mods;
00536 
00537     if ( !this_interactive() || !previous_object() )
00538         return 0;
00539 
00540     if ( !IS_ARCH(this_interactive()) || !IS_ARCH(getuid(previous_object())) ||
00541          process_call() )
00542         log_file( "UNDIE", sprintf( "%s %O -> %O\n", dtime(time())[5..16],
00543                                     this_interactive(), ME ) );
00544 
00545     if ( x = Query(P_DEADS) )
00546         x--;
00547 
00548     Set( P_DEADS, x );
00549 
00550     x = QueryProp(P_XP);
00551 
00552     if ( (di = QueryProp(P_LEVEL)) < 20 || !IS_SEER(ME) )
00553         x = (int)(x * 1.5);
00554     else
00555         // Umweg ueber float, weil bei hohen XP+Level sonst 32Bit nicht
00556         // mehr ausreichen -> negative XP
00557         x = (int) ( x * ((float) (di - 17) / (di - 18)) );
00558 
00559     Set( P_XP, x );
00560 
00561     attr = QueryProp(P_ATTRIBUTES) || ([]);
00562     mods = QueryProp(P_ATTRIBUTES_MODIFIER)["#death"] || ([]);
00563 
00564     if ( mappingp(di = QueryProp(P_DEATH_INFO)) ){
00565         // Beim naechsten heart_beat checken
00566                 // Zesstra: Wieso eigentlich? Die Modifier werden doch direkt hier
00567                 // geloescht. So expired man auch einen Teil von nicht-undie-ten Toden
00568                 // vorzeitig...? Mal auskommentiert. 29.10.2007
00569         //di[A_STR] = 1;
00570         //di[A_DEX] = 1;
00571         //di[A_INT] = 1;
00572         //di[A_CON] = 1;
00573     }
00574     else
00575       di = ([]);
00576     
00577     mods[A_STR] = ((4 * (attr[A_STR] + mods[A_STR])) / 3) - attr[A_STR];
00578     mods[A_DEX] = ((4 * (attr[A_DEX] + mods[A_DEX])) / 3) - attr[A_DEX];
00579     mods[A_INT] = ((4 * (attr[A_INT] + mods[A_INT])) / 3) - attr[A_INT];
00580     mods[A_CON] = ((4 * (attr[A_CON] + mods[A_CON])) / 3) - attr[A_CON];
00581 
00582     if ( mods[A_STR] >= 0 ) {
00583         efun::m_delete( mods, A_STR );
00584                 efun::m_delete( di, A_STR);
00585     }
00586     if ( mods[A_DEX] >= 0 ) {
00587         efun::m_delete( mods, A_DEX );
00588                 efun::m_delete( di, A_DEX);
00589     }
00590     if ( mods[A_INT] >= 0 ) {
00591         efun::m_delete( mods, A_INT );
00592                 efun::m_delete( di, A_INT);
00593     }
00594     if ( mods[A_CON] >= 0 ) {
00595         efun::m_delete( mods, A_CON );
00596                 efun::m_delete( di, A_CON);
00597     }
00598 
00599     SetProp( P_ATTRIBUTES_MODIFIER, ({ "#death", mods }) );
00600     if (sizeof(di))
00601       SetProp( P_DEATH_INFO, di );
00602     else
00603       SetProp( P_DEATH_INFO, 0);
00604 
00605     suffer_time -= ((SUFFER_TIME)-1);
00606 
00607     if ( suffer_time < 0 )
00608         suffer_time = 0;
00609 
00610     Set( P_GHOST, 0 );
00611     return 1;
00612 }


Variablen-Dokumentation

private nosave int die_in_progress

Definiert in Zeile 48 der Datei life.c.

inherit std living life

Definiert in Zeile 15 der Datei life.c.

private int suffer_time

Definiert in Zeile 46 der Datei life.c.

int time_to_save [static]

Definiert in Zeile 47 der Datei life.c.

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