#include <combat.h>#include <language.h>#include <properties.h>#include <wizlevels.h>#include <health.h>#include <new_skills.h>
gehe zum Quellcode dieser Datei
Makrodefinitionen | |
| #define | HB_CHECK 7 |
| #define | ME this_object() |
| #define | STATMASTER "/p/service/rochus/guildstat/master" |
| #define | SPELL_TOTALRATE 0 |
| #define | SPELL_DAMAGE 1 |
| #define | SPELL_TEXT_FOR_ENEMY 2 |
| #define | SPELL_TEXT_FOR_OTHERS 3 |
| #define | SPELL_DAMTYPE 4 |
| #define | SPELL_FUNC 5 |
| #define | SPELL_ARG 6 |
| #define | TJ(x) |
Funktionen | |
| private void | catch_up_hbs () |
| protected void | create () |
| protected void | create_super () |
| void | reset () |
| static void | _set_max_hp (int i) |
| static void | _set_max_sp (int i) |
| static mixed | _check_immortality () |
| public void | make_immortal () |
| static int | _query_hb () |
| varargs int | AddSpell (int rate, int damage, string TextForEnemy, string TextForOthers, mixed dam_type, mixed func, mixed spellarg) |
| int | AutoAttack (object ob) |
| void | SpellAttack (object enemy) |
| protected void | heart_beat () |
| void | init () |
| int | Defend (int dam, mixed dam_type, mixed spell, object enemy) |
Variablen | |
| inherit std living | combat |
| nosave int | heartbeat |
| nosave int | beatcount |
| static private closure | mod_att_stat |
| #define HB_CHECK 7 |
Definiert in Zeile 21 der Datei combat.c.
Wird benutzt von heart_beat().
| #define SPELL_ARG 6 |
Definiert in Zeile 117 der Datei combat.c.
Wird benutzt von heart_beat().
| #define SPELL_DAMAGE 1 |
Definiert in Zeile 112 der Datei combat.c.
Wird benutzt von heart_beat().
| #define SPELL_DAMTYPE 4 |
Definiert in Zeile 115 der Datei combat.c.
Wird benutzt von heart_beat().
| #define SPELL_FUNC 5 |
Definiert in Zeile 116 der Datei combat.c.
Wird benutzt von heart_beat().
| #define SPELL_TEXT_FOR_ENEMY 2 |
Definiert in Zeile 113 der Datei combat.c.
Wird benutzt von heart_beat().
| #define SPELL_TEXT_FOR_OTHERS 3 |
Definiert in Zeile 114 der Datei combat.c.
Wird benutzt von heart_beat().
| #define SPELL_TOTALRATE 0 |
Definiert in Zeile 111 der Datei combat.c.
Wird benutzt von heart_beat().
| #define STATMASTER "/p/service/rochus/guildstat/master" |
| static mixed _check_immortality | ( | ) | [static] |
Definiert in Zeile 60 der Datei combat.c.
Benutzt beatcount, break_string(), F_QUERY_METHOD, heartbeat, name, P_NO_ATTACK, Query(), Set() und WER.
00061 { 00062 int t; 00063 00064 if ( !(t = Query("time_to_mortality")) || time() > t ){ 00065 // Zeit ist abgelaufen - wieder angreifbar machen 00066 Set( P_NO_ATTACK, 0, F_QUERY_METHOD ); 00067 heartbeat = 1; 00068 beatcount = 1; 00069 set_heart_beat(1); 00070 00071 return 0; 00072 } 00073 00074 // der NPC ist noch unangreifbar 00075 return break_string( capitalize(name( WER, 1 )) + " versteckt sich hinter " 00076 "einem Fehler im Raum-Zeit-Gefuege und entgeht so " 00077 "voruebergehend allen Angriffen.", 78 ); 00078 }

| static int _query_hb | ( | ) | [static] |
Definiert in Zeile 103 der Datei combat.c.
Benutzt F_VALUE, InFight(), P_HB und Query().
00104 { 00105 // TODO: return InFight() || Query(P_HB, F_VALUE), sobald InFight() 00106 // geaendert. 00107 return (InFight() || Query(P_HB,F_VALUE)) ? 1 : 0; 00108 }

| static void _set_max_hp | ( | int | i | ) | [static] |
| static void _set_max_sp | ( | int | i | ) | [static] |
| varargs int AddSpell | ( | int | rate, | |
| int | damage, | |||
| string | TextForEnemy, | |||
| string | TextForOthers, | |||
| mixed | dam_type, | |||
| mixed | func, | |||
| mixed | spellarg | |||
| ) |
Definiert in Zeile 119 der Datei combat.c.
Benutzt DT_MAGIC, P_SPELLS, Query() und Set().
00120 { 00121 mixed *spells; 00122 int total_rates; 00123 00124 if (rate<0 || damage<=0 || !stringp(TextForEnemy) || 00125 !stringp(TextForOthers)) 00126 return 0; 00127 if (!dam_type) 00128 dam_type = DT_MAGIC; 00129 if (!spellarg) 00130 spellarg=1; 00131 total_rates=Query("npc:total_rates")+rate; 00132 spells=Query(P_SPELLS); 00133 if (!pointerp(spells)) 00134 spells=({}); 00135 spells+=({({total_rates, damage, TextForEnemy, TextForOthers, 00136 dam_type, func, spellarg})}); 00137 Set(P_SPELLS,spells); 00138 Set("npc:total_rates",total_rates); 00139 return 1; 00140 }

| int AutoAttack | ( | object | ob | ) |
Definiert in Zeile 142 der Datei combat.c.
Benutzt i, IS_LEARNER, P_AGGRESSIVE, P_WANTS_TO_LEARN, QueryProp() und x.
Wird benutzt von heart_beat() und init().
00142 { 00143 mixed m; 00144 00145 if (!query_once_interactive(ob)) 00146 return 0; 00147 if (mappingp(m=QueryProp(P_AGGRESSIVE))) { 00148 mixed *ind,x,z; 00149 float f; 00150 int i,n; 00151 00152 ind=m_indices(m)-({0});n=0;f=0.0; 00153 for (i=sizeof(ind)-1;i>=0;i--) { 00154 x=ind[i]; 00155 if ((z=m[x][ob->QueryProp(x)]) || (z=m[x][0])) { 00156 f=f+(float)z; 00157 n++; 00158 } 00159 } 00160 if (n) 00161 m=f/((float)n); 00162 else 00163 m=m[0]; 00164 } 00165 if (((int)(100*(m+ob->QueryProp(P_AGGRESSIVE))))<=random(100)) 00166 return 0; 00167 if (IS_LEARNER(ob) 00168 && (ob->QueryProp(P_INVIS) 00169 || ob->QueryProp(P_WANTS_TO_LEARN))) 00170 return 0; 00171 return 1; 00172 }


| private void catch_up_hbs | ( | ) |
Definiert in Zeile 299 der Datei combat.c.
Benutzt absolute_hb_count(), alc, ALCOHOL_DELAY, HEAL_DELAY, heartbeat, NO_REG_HP, NO_REG_SP, P_ALCOHOL, P_DISABLE_ATTACK, P_HP, P_NO_REGENERATION, P_SP, Query(), QueryProp(), Set(), SetProp(), log_buffer_s::sp und update_hunt_times().
Wird benutzt von init() und reset().
00299 { 00300 // gibt es HBs zum nachholen? 00301 int beat_off_num = Query("npc:beat_off_num"); 00302 if (!beat_off_num) 00303 return; // nein. 00304 // wieviele HBs nachholen? 00305 beat_off_num = absolute_hb_count() - beat_off_num; 00306 00307 if (beat_off_num>0) { 00308 // Nicht ausgefuehrtes HEILEN nachholen 00309 int rlock=QueryProp(P_NO_REGENERATION); 00310 int hp=QueryProp(P_HP); 00311 int sp=QueryProp(P_SP); 00312 int alc=QueryProp(P_ALCOHOL); 00313 if (!(rlock & NO_REG_HP)) { 00314 hp+=beat_off_num/HEAL_DELAY+alc/ALCOHOL_DELAY; 00315 SetProp(P_HP,hp); 00316 } 00317 if (!(rlock & NO_REG_SP)) { 00318 sp+=beat_off_num/HEAL_DELAY+alc/ALCOHOL_DELAY; 00319 SetProp(P_SP,sp); 00320 } 00321 alc-=beat_off_num/ALCOHOL_DELAY; 00322 if ( alc < 0 ) 00323 alc = 0; 00324 SetProp(P_ALCOHOL,alc); 00325 int da = QueryProp(P_DISABLE_ATTACK); 00326 // Paralysen abbauen 00327 if ( da > 0 ) { 00328 da -= beat_off_num; 00329 if ( da < 0 ) 00330 da = 0; 00331 SetProp( P_DISABLE_ATTACK, da ); 00332 } 00333 // Hunttimes aktualisieren, Feinde expiren 00334 update_hunt_times(beat_off_num); 00335 if (!heartbeat) 00336 // HBs immer noch abgeschaltet, naechstes Mal HBs seit jetzt nachholen. 00337 Set("npc:beat_off_num",absolute_hb_count()); 00338 else 00339 // HB laeuft wieder, nix mehr nachholen, bis zur naechsten Abschaltung. 00340 Set("npc:beat_off_num",0); 00341 } 00342 }


| protected void create | ( | ) |
| protected void create_super | ( | ) |
Definiert in Zeile 35 der Datei combat.c.
Benutzt set_next_reset().
00035 { 00036 set_next_reset(-1); 00037 }

| int Defend | ( | int | dam, | |
| mixed | dam_type, | |||
| mixed | spell, | |||
| object | enemy | |||
| ) |
Definiert in Zeile 359 der Datei combat.c.
Benutzt Defend(), IS_LEARNER, P_GUILD, P_GUILD_LEVEL und STATMASTER.
00359 { 00360 if (objectp(enemy=(enemy||this_player())) 00361 && query_once_interactive(enemy) 00362 && !IS_LEARNER(enemy)) { 00363 if (!objectp(get_type_info(mod_att_stat,2))) { 00364 object ma; 00365 if (!objectp(ma=find_object(STATMASTER))) 00366 return ::Defend(dam,dam_type,spell,enemy); 00367 // Keine Statistik wenn Master nicht geladen ist. 00368 mod_att_stat=symbol_function("ModifyAttackStat",ma); 00369 } 00370 funcall(mod_att_stat, 00371 enemy->QueryProp(P_GUILD), 00372 enemy->QueryProp(P_GUILD_LEVEL), 00373 dam, 00374 dam_type, 00375 spell); 00376 } 00377 00378 return ::Defend(dam,dam_type,spell,enemy); 00379 }

| protected void heart_beat | ( | ) |
Definiert in Zeile 187 der Datei combat.c.
Benutzt AutoAttack(), beatcount, env(), HB_CHECK, heartbeat, i, Kill(), MAX_ABILITY, ME, MT_ANGRIFF, P_DISABLE_ATTACK, P_GHOST, P_HB, P_LEVEL, P_POISON, P_SPELLRATE, P_SPELLS, Query(), QueryProp(), SelectEnemy(), SI_MAGIC_TYPE, SP_PHYSICAL_ATTACK, SPELL_ARG, SPELL_DAMAGE, SPELL_DAMTYPE, SPELL_FUNC, SPELL_TEXT_FOR_ENEMY, SPELL_TEXT_FOR_OTHERS, SPELL_TOTALRATE, SpellAttack(), WEM, WEN, WER und WESSEN.
00187 { 00188 int r,i; 00189 string akt_spell_mess; 00190 mixed env,*spells, sinfo; 00191 object enemy; 00192 00193 if ( --beatcount < 0 ) 00194 beatcount = 0; 00195 00196 if (!beatcount && !Query(P_HB)) { 00197 if (!environment()) { 00198 set_heart_beat(0); 00199 heartbeat = 0; 00200 if( clonep(this_object()) ) remove(); 00201 return; 00202 } 00203 if (!QueryProp(P_POISON)) { 00204 // Spieler anwesend? 00205 env = filter(all_inventory(environment()), #'query_once_interactive); 00206 if (!sizeof(env)) { 00207 // Nein, HBs abschalten. 00208 set_heart_beat(0); 00209 heartbeat=0; 00210 TJ("OFF\n"); 00211 beatcount=HB_CHECK; 00212 Set("npc:beat_off_num",absolute_hb_count()); 00213 return; 00214 } 00215 } 00216 } 00217 ::heart_beat(); 00218 if (!ME) 00219 return; 00220 enemy=SelectEnemy(); 00221 if (QueryProp(P_AGGRESSIVE) 00222 && (!enemy || environment()!=environment(enemy)) 00223 && !beatcount) { 00224 beatcount=HB_CHECK; 00225 env=filter(all_inventory(environment()),#'AutoAttack); 00226 if (!sizeof(env)) 00227 return; 00228 i=random(sizeof(env)); 00229 Kill(env[i]); 00230 } 00231 else if (!beatcount) 00232 beatcount=HB_CHECK; 00233 if (!objectp(enemy) ||QueryProp(P_DISABLE_ATTACK)>0) 00234 return; 00235 SpellAttack(enemy); 00236 00237 if (!pointerp(spells=Query(P_SPELLS)) 00238 || !sizeof(spells) 00239 || !objectp(enemy=SelectEnemy()) 00240 || environment(enemy)!=environment() 00241 || (QueryProp(P_DISABLE_ATTACK)>0) 00242 || random(100)>Query(P_SPELLRATE)) 00243 return; 00244 r=random(Query("npc:total_rates")); 00245 for (i=sizeof(spells)-1;(i>0 && spells[i-1][SPELL_TOTALRATE]>r);i--) 00246 ; 00247 tell_object(enemy, spells[i][SPELL_TEXT_FOR_ENEMY]); 00248 if (stringp(akt_spell_mess=spells[i][SPELL_TEXT_FOR_OTHERS])) { 00249 if ((r=strstr(akt_spell_mess,"@WER",0))!=-1) 00250 if (!r) 00251 akt_spell_mess= 00252 implode(explode(akt_spell_mess,"@WER"),enemy->Name(WER,1)); 00253 else 00254 akt_spell_mess= 00255 implode(explode(akt_spell_mess,"@WER"),enemy->name(WER,1)); 00256 if (strstr(akt_spell_mess,"@WESSEN",0)!=-1) 00257 akt_spell_mess= 00258 implode(explode(akt_spell_mess,"@WESSEN"), 00259 enemy->name(WESSEN,1)); 00260 if (strstr(akt_spell_mess,"@WEM",0)!=-1) 00261 akt_spell_mess= 00262 implode(explode(akt_spell_mess,"@WEM"),enemy->name(WEM,1)); 00263 if (strstr(akt_spell_mess,"@WEN",0)!=-1) 00264 akt_spell_mess= 00265 implode(explode(akt_spell_mess,"@WEN"),enemy->name(WEN,1)); 00266 say(akt_spell_mess,({enemy, this_object()})); 00267 } 00268 sinfo = deep_copy(spells[i][SPELL_ARG]); 00269 if(!mappingp(sinfo)) 00270 sinfo=([ SI_MAGIC_TYPE :({ MT_ANGRIFF }) ]); 00271 else if(!sinfo[SI_MAGIC_TYPE]) 00272 sinfo[ SI_MAGIC_TYPE]=({ MT_ANGRIFF }); 00273 if(!sinfo[SP_PHYSICAL_ATTACK] && 00274 (enemy->SpellDefend(this_object(),sinfo) > 00275 random(MAX_ABILITY+QueryProp(P_LEVEL)*50))){ 00276 tell_object(enemy,"Du wehrst den Spruch ab.\n"); 00277 say(enemy->Name(WER,1)+" wehrt den Spruch ab.\n", 00278 ({ enemy, this_object()})); 00279 return ; 00280 } 00281 enemy->Defend(r=random(spells[i][SPELL_DAMAGE])+1, 00282 spells[i][SPELL_DAMTYPE], 00283 spells[i][SPELL_ARG], 00284 this_object()); 00285 00286 // Falls der Gegner (oder wir) im Defend stirbt, hier abbrechen 00287 if ( !objectp(ME) || !objectp(enemy) 00288 || enemy->QueryProp(P_GHOST) ) return; 00289 00290 if (spells[i][SPELL_FUNC] && stringp(spells[i][SPELL_FUNC])) 00291 catch(call_other(this_object(), 00292 spells[i][SPELL_FUNC], 00293 enemy, 00294 r, // Damage 00295 spells[i][SPELL_DAMTYPE]);publish); 00296 }

| void init | ( | ) |
Definiert in Zeile 344 der Datei combat.c.
Benutzt AutoAttack(), catch_up_hbs(), heartbeat und Kill().
00344 { 00345 00346 // ggf. Heartbeats nachholen und wieder einschalten. 00347 if (!heartbeat) { 00348 set_heart_beat(1); 00349 heartbeat=1; 00350 catch_up_hbs(); 00351 } 00352 00353 if (AutoAttack(this_player())) 00354 Kill(this_player()); 00355 }

| public void make_immortal | ( | ) |
Definiert in Zeile 82 der Datei combat.c.
Benutzt P_NO_ATTACK, QueryProp() und Set().
00083 { 00084 // fuer 5 Minuten unangreifbar machen 00085 Set( P_NO_ATTACK, #'_check_immortality, F_QUERY_METHOD ); 00086 00087 Set( "time_to_mortality", time() + 300, F_VALUE ); 00088 00089 // damit die Spieler keinen Vorteil durch den Bug haben, heilen 00090 heal_self(10000); 00091 00092 // da nun der Heartbeat abgeschaltet ist und normalerweise erst 00093 // reaktiviert wird, sobald jemand nach 5min P_NO_ATTACK abfragt, muss man 00094 // aber auf Viecher achten, die immer nen Heartbeat haben wollen. In dem 00095 // fall per call_out selber die Prop abfragen. 00096 if (QueryProp(P_HB)) 00097 call_out(#'QueryProp, 301, P_NO_ATTACK); 00098 }

| void reset | ( | void | ) |
Definiert in Zeile 42 der Datei combat.c.
Benutzt catch_up_hbs() und heartbeat.
00042 { 00043 // ggf. die abgeschalteten HBs nachholen. 00044 if (!heartbeat) 00045 catch_up_hbs(); 00046 }

| void SpellAttack | ( | object | enemy | ) |
Definiert in Zeile 174 der Datei combat.c.
Wird benutzt von heart_beat().

| nosave int beatcount |
Definiert in Zeile 25 der Datei combat.c.
Wird benutzt von _check_immortality(), create() und heart_beat().
| nosave int heartbeat |
Definiert in Zeile 25 der Datei combat.c.
Wird benutzt von _check_immortality(), catch_up_hbs(), create(), heart_beat(), init() und reset().
private closure mod_att_stat [static] |
1.6.3