예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
파일: sc_spell.cpp 프로젝트: coleb/Raid-Sim
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;
}
예제 #4
0
파일: sc_spell.cpp 프로젝트: coleb/Raid-Sim
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;
}
예제 #5
0
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 );
}
예제 #6
0
/* 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);
                }
            }
        }
    }
}
예제 #7
0
void s_haste(void)
{
    haste(0);
}
예제 #8
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;
}
예제 #9
0
/* potion of speed */
void i_speed(pob o)
{
    if (o->blessing > -1)
        Objects[o->id].known = 1;
    haste(o->blessing);
}