void action_t::execute() { if ( sim -> log && ! dual ) { log_t::output( sim, "%s performs %s (%.0f)", player -> name(), name(), player -> resource_current[ player -> primary_resource() ] ); } if ( observer ) *observer = 0; player_buff(); target_debuff( DMG_DIRECT ); calculate_result(); consume_resource(); if ( result_is_hit() ) { calculate_direct_damage(); if ( direct_dmg > 0 ) { assess_damage( direct_dmg, DMG_DIRECT ); } if ( num_ticks > 0 ) { if ( dot_behavior == DOT_REFRESH ) { current_tick = 0; if ( ! ticking ) schedule_tick(); } else { if ( ticking ) cancel(); snapshot_haste = haste(); schedule_tick(); } } } else { if ( sim -> log ) { log_t::output( sim, "%s avoids %s (%s)", sim -> target -> name(), name(), util_t::result_type_string( result ) ); log_t::miss_event( this ); } } update_ready(); if ( ! dual ) update_stats( DMG_DIRECT ); schedule_travel(); if ( repeating && ! proc ) schedule_execute(); if ( harmful ) player -> in_combat = true; }
void action_t::schedule_tick() { if ( sim -> debug ) log_t::output( sim, "%s schedules tick for %s", player -> name(), name() ); if ( current_tick == 0 ) { if ( school == SCHOOL_BLEED ) sim -> target -> debuffs.bleeding -> increment(); if ( tick_zero ) { time_to_tick = 0; tick(); } } ticking = 1; if ( snapshot_haste <= 0.0 ) { snapshot_haste = haste(); } time_to_tick = tick_time(); tick_event = new ( sim ) action_tick_event_t( sim, this, time_to_tick ); if ( channeled ) player -> channeling = this; if ( observer ) *observer = this; }
double spell_t::gcd() const { double t = action_t::gcd(); if ( t == 0 ) return 0; t *= haste(); if ( t < min_gcd ) t = min_gcd; return t; }
double spell_t::execute_time() const { double t = base_execute_time; if ( ! harmful && ! player -> in_combat ) return 0; if ( player -> buffs.corruption_absolute -> up() ) return 0; if ( t <= 0 ) return 0; t *= haste(); return t; }
void heal_t::player_buff() { player_multiplier = 1.0; player_dd_multiplier = 1.0; player_td_multiplier = 1.0; player_hit = 0; player_crit = 0; player_penetration = 0; player_dd_adder = 0; player_spell_power = 0; player_attack_power = 0; player_spell_power_multiplier = 1.0; player_attack_power_multiplier = 1.0; player_t* p = player; player_hit = p -> composite_spell_hit(); player_crit = p -> composite_spell_crit(); player_multiplier = p -> composite_player_heal_multiplier ( school ); player_dd_multiplier = p -> composite_player_dh_multiplier( school ); player_td_multiplier = p -> composite_player_th_multiplier( school ); if ( base_attack_power_multiplier > 0 ) { player_attack_power = p -> composite_attack_power(); player_attack_power_multiplier = p -> composite_attack_power_multiplier(); } if ( base_spell_power_multiplier > 0 ) { player_spell_power = p -> composite_spell_power( school ); player_spell_power_multiplier = p -> composite_spell_power_multiplier(); } player_haste = haste(); if ( sim -> debug ) log_t::output( sim, "heal_t::player_buff: %s hit=%.2f crit=%.2f pen=%.0f sp=%.2f ap=%.2f mult=%.2f ", name(), player_hit, player_crit, player_penetration, player_spell_power, player_attack_power, player_multiplier ); }
/* Has all kinds of effects in different circumstances. Eventually will be more interesting */ void s_ritual(void) { pob symbol; int i,roomno; int x,y; mprint("You begin your ritual...."); mprint("You enter a deep trance. Time Passes..."); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); if (RitualHour == hour()) mprint("Your mental fatigue prevents from completing the ritual!"); else if (random_range(100) > Player.iq+Player.pow+Player.level) mprint("Your concentration was broken -- the ritual fails!"); else { mprint("You charge the ritual with magical energy and focus your will."); mprint("Time Passes..."); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); setgamestatus(SKIP_PLAYER); time_clock(FALSE); RitualHour = hour(); /* set of random conditions for different ritual effects */ if (Current_Environment == E_CITY) { mprint("Flowing waves of mystical light congeal all around you."); mprint("'Like wow, man! Colors!'"); mprint("Appreciative citizens throw you spare change."); Player.cash +=random_range(50); } else if ( (roomno=Level->site[Player.x][Player.y].roomnumber) >= ROOMBASE ) { if (RitualRoom == roomno) mprint("For some reason the ritual doesn't work this time..."); else { RitualRoom = roomno; switch (RitualRoom) { case RS_TREASURE: /* ransacked treasure chamber */ mprint("Your spell sets off frenetic growth all around you!"); for(i=0; i<8; i++) { Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].locchar = HEDGE; Level->site[Player.x+Dirs[0][i]][Player.y+Dirs[1][i]].p_locf = L_TRIFID; lset(Player.x+Dirs[0][i], Player.y+Dirs[1][i], CHANGED); } break; case RS_HAREM: /* harem */ case RS_BOUDOIR: /* boudoir */ mprint("A secret panel opens next to the bed...."); if (random_range(2)) summon(0,INCUBUS); /* succubus/incubus */ else summon(0,SATYR); /* satyr/nymph */ break; case RS_SHRINE: /*shrine to high magic */ mprint("A storm of mana coaelesces around you."); mprint("You are buffeted by bursts of random magic."); p_damage(random_range(Player.pow),UNSTOPPABLE,"high magic"); mprint("Continue ritual? Could be dangerous.... [yn] "); if (ynq()=='y') s_wish(); else mprint("The mana fades away to nothingness."); x = Player.x; y = Player.y; while (x >= 0 && Level->site[x - 1][y].roomnumber == RS_SHRINE) x--; while (y >= 0 && Level->site[x][y - 1].roomnumber == RS_SHRINE) y--; for (i = 0; Level->site[x][y].roomnumber == RS_SHRINE;) { Level->site[x][y].roomnumber = RS_ZORCH; lset(x, y, CHANGED); x++; i++; if (Level->site[x][y].roomnumber != RS_SHRINE) { x -= i; i = 0; y++; } } break; case RS_MAGIC_LAB: /* magician's lab */ mprint("Your magical activity sets off a latent spell in the lab!"); cast_spell(random_range(NUMSPELLS)); break; case RS_PENTAGRAM: /* pentagram room */ mprint("A smoky form begins to coalesce...."); summon(-1,-1); mprint("Fortunately, it seems confined to the pentagram."); m_status_reset(Level->mlist->m,MOBILE); break; case RS_OMEGA_DAIS: /* blue omega room */ mprint("The Lords of Destiny look upon you...."); if (Player.level > 10) { mprint("A curtain of blue flames leaps up from the omega."); morewait(); l_adept(); } else { if (Player.patron == DESTINY) { mprint("Your patrons take pity on you."); if ((Player.rank[PRIESTHOOD]<SPRIEST) && (! find_item(&symbol,OB_SYMBOL_DESTINY,-1))) { symbol = ((pob) checkmalloc(sizeof(objtype))); *symbol = Objects[OB_SYMBOL_DESTINY]; symbol->known = 2; symbol->charge = 17; gain_item(symbol); mprint("You feel uplifted."); } else gain_experience(min(1000,Player.xp)); } else if (random_range(3)==1) { mprint("You feel Fated."); gain_experience(Player.level*Player.level*10); Player.hp = max(Player.hp, Player.maxhp); } else if (random_range(2)) { mprint("You feel Doomed."); Player.hp = 1; Player.mana = 0; Player.xp = 0; } else mprint("The Lords of Destiny laugh at you!"); } break; default: mprint("Well, not much effect. Chalk it up to experience."); gain_experience(Player.level*5); break; } } } else { if (RitualRoom == Level->site[Player.x][Player.y].roomnumber) mprint("The ritual fails for some unexplainable reason."); else { mprint("The ritual seems to be generating some spell effect."); RitualRoom = Level->site[Player.x][Player.y].roomnumber; switch (RitualRoom) { case RS_WALLSPACE: shadowform(); break; case RS_CORRIDOR: haste(0); break; case RS_PONDS: breathe(0); break; case RS_ADEPT: hero(1); break; default: mprint("The ritual doesn't seem to produce any tangible results..."); gain_experience(Player.level*6); } } } } }
void s_haste(void) { haste(0); }
bool action_t::ready() { target_t* t = sim -> target; if ( player -> skill < 1.0 ) if ( ! sim -> roll( player -> skill ) ) return false; bool check_duration = true; if ( ( scale_ticks_with_haste() > 0 ) && ( haste_gain_percentage > 0.0 ) && ( ticking ) ) { check_duration = ( ( snapshot_haste / haste() - 1.0 ) * 100.0 ) <= haste_gain_percentage; } if ( recast ) { check_duration = false; } if ( check_duration ) { double remains = dot -> remains(); if ( remains > 0 ) { double delta = remains - execute_time(); if ( delta > 3.0 ) return false; if ( delta > 0 && sim -> roll( player -> skill ) ) return false; } } if ( cooldown -> remains() > 0 ) return false; if ( ! player -> resource_available( resource, cost() ) ) return false; if ( min_current_time > 0 ) if ( sim -> current_time < min_current_time ) return false; if ( max_current_time > 0 ) if ( sim -> current_time > max_current_time ) return false; if ( min_time_to_die > 0 ) if ( sim -> target -> time_to_die() < min_time_to_die ) return false; if ( max_time_to_die > 0 ) if ( sim -> target -> time_to_die() > max_time_to_die ) return false; if ( min_health_percentage > 0 ) if ( sim -> target -> health_percentage() < min_health_percentage ) return false; if ( max_health_percentage > 0 ) if ( sim -> target -> health_percentage() > max_health_percentage ) return false; if ( max_haste > 0 ) if ( ( ( 1.0 / haste() ) - 1.0 ) > max_haste ) return false; if ( bloodlust_active > 0 ) if ( ! player -> buffs.bloodlust -> check() ) return false; if ( bloodlust_active < 0 ) if ( player -> buffs.bloodlust -> check() ) return false; if ( sync_action && ! sync_action -> ready() ) return false; if ( sim -> target -> debuffs.invulnerable -> check() ) if ( harmful ) return false; if ( player -> buffs.moving -> check() ) if ( channeled || ( range == 0 ) || ( execute_time() > 0 ) ) return false; if ( P400 != -1 ) if ( P400 != sim -> P400 ) return false; if ( moving != -1 ) if ( moving != ( player -> buffs.moving -> check() ? 1 : 0 ) ) return false; if ( vulnerable ) if ( ! t -> debuffs.vulnerable -> check() ) return false; if ( invulnerable ) if ( ! t -> debuffs.invulnerable -> check() ) return false; if ( if_expr ) { int result_type = if_expr -> evaluate(); if ( result_type == TOK_NUM ) return if_expr -> result_num != 0; if ( result_type == TOK_STR ) return true; if ( result_type == TOK_UNKNOWN ) return false; } return true; }
/* potion of speed */ void i_speed(pob o) { if (o->blessing > -1) Objects[o->id].known = 1; haste(o->blessing); }