class Natural20::DieRoll

Attributes

die_sides[R]
modifier[R]
roller[R]
rolls[R]

Public Class Methods

new(rolls, modifier, die_sides = 20, advantage: false, disadvantage: false, description: nil, roller: nil) click to toggle source

This represents a dice roll @param rolls [Array] Integer dice roll representations @param modifier [Integer] a constant value to add to the roll

# File lib/natural_20/die_roll.rb, line 126
def initialize(rolls, modifier, die_sides = 20, advantage: false, disadvantage: false, description: nil, roller: nil)
  @rolls = rolls
  @modifier = modifier
  @die_sides = die_sides
  @advantage = advantage
  @disadvantage = disadvantage
  @description = description
  @roller = roller
end
numeric?(c) click to toggle source
# File lib/natural_20/die_roll.rb, line 212
def self.numeric?(c)
  return true if c =~ /\A\d+\Z/

  begin
    true if Float(c)
  rescue StandardError
    false
  end
end
parse(roll_str) click to toggle source

@param die_roll_str [String] @return [Natural20::DieRollDetail]

# File lib/natural_20/die_roll.rb, line 243
def self.parse(roll_str)
  die_count_str = ''
  die_type_str = ''
  modifier_str = ''
  modifier_op = ''
  state = :initial

  roll_str.strip.each_char do |c|
    case state
    when :initial
      if numeric?(c)
        die_count_str << c
      elsif c == 'd'
        state = :die_type
      elsif c == '+'
        state = :modifier
      end
    when :die_type
      next if c == ' '

      if numeric?(c)
        die_type_str << c
      elsif c == '+'
        state = :modifier
      elsif c == '-'
        modifier_op = '-'
        state = :modifier
      end
    when :modifier
      next if c == ' '

      modifier_str << c if numeric?(c)
    end
  end

  if state == :initial
    modifier_str = die_count_str
    die_count_str = '0'
  end

  number_of_die = die_count_str.blank? ? 1 : die_count_str.to_i

  detail = Natural20::DieRollDetail.new
  detail.die_count = number_of_die
  detail.die_type = die_type_str
  detail.modifier = modifier_str
  detail.modifier_op = modifier_op
  detail
end
roll(roll_str, crit: false, disadvantage: false, advantage: false, description: nil, entity: nil, battle: nil) click to toggle source

Rolls the dice, details on dice rolls and its values are preserved @param roll_str [String] A dice roll expression @param entity [Natural20::Entity] @param crit [Boolean] A critial hit damage roll - double dice rolls @param advantage [Boolean] Roll with advantage, roll twice and select the highest @param disadvantage [Boolean] Roll with disadvantage, roll twice and select the lowest @param battle [Natural20::Battle] @return [Natural20::DieRoll]

# File lib/natural_20/die_roll.rb, line 301
def self.roll(roll_str, crit: false, disadvantage: false, advantage: false, description: nil, entity: nil, battle: nil)
  roller = Roller.new(roll_str, crit: crit, disadvantage: disadvantage, advantage: advantage,
                                description: description, entity: entity, battle: battle)
  roller.roll
end
roll_with_lucky(entity, roll_str, crit: false, disadvantage: false, advantage: false, description: nil, battle: nil) click to toggle source

Rolls the dice checking lucky feat, details on dice rolls and its values are preserved @param entity [Natural20::Entity] @param roll_str [String] A dice roll expression @param entity [Natural20::Entity] @param crit [Boolean] A critial hit damage roll - double dice rolls @param advantage [Boolean] Roll with advantage, roll twice and select the highest @param disadvantage [Boolean] Roll with disadvantage, roll twice and select the lowest @param battle [Natural20::Battle] @return [Natural20::DieRoll]

# File lib/natural_20/die_roll.rb, line 316
def self.roll_with_lucky(entity, roll_str, crit: false, disadvantage: false, advantage: false, description: nil, battle: nil)
  roller = Roller.new(roll_str, crit: crit, disadvantage: disadvantage, advantage: advantage,
                                description: description, entity: entity, battle: battle)
  result = roller.roll
  if result.nat_1? && entity.class_feature?('lucky')
    roller.roll(lucky: true)
  else
    result
  end
end
t(key, options = {}) click to toggle source
# File lib/natural_20/die_roll.rb, line 327
def self.t(key, options = {})
  I18n.t(key, **options)
end

Public Instance Methods

+(other) click to toggle source
# File lib/natural_20/die_roll.rb, line 232
def +(other)
  if other.is_a?(DieRolls)
    other.add_to_front(self)
    other
  else
    DieRolls.new([self, other])
  end
end
<=>(other) click to toggle source
# File lib/natural_20/die_roll.rb, line 228
def <=>(other)
  result <=> other.result
end
==(other) click to toggle source
# File lib/natural_20/die_roll.rb, line 222
def ==(other)
  return true if other.rolls == @rolls && other.modifier == @modifier && other.die_sides == @die_sides

  false
end
color_roll(roll) click to toggle source

adds color flair to the roll depending on value @param roll [String,Integer] @return [String]

# File lib/natural_20/die_roll.rb, line 179
def color_roll(roll)
  case roll
  when 1
    roll.to_s.colorize(:red)
  when @die_sides
    roll.to_s.colorize(:green)
  else
    roll.to_s
  end
end
nat_1?() click to toggle source
# File lib/natural_20/die_roll.rb, line 148
def nat_1?
  if @advantage
    @rolls.map(&:max).detect { |r| r == 1 }
  elsif @disadvantage
    @rolls.map(&:min).detect { |r| r == 1 }
  else
    @rolls.include?(1)
  end
end
nat_20?() click to toggle source

This is a natural 20 or critical roll @return [Boolean]

# File lib/natural_20/die_roll.rb, line 138
def nat_20?
  if @advantage
    @rolls.map(&:max).detect { |r| r == 20 }
  elsif @disadvantage
    @rolls.map(&:min).detect { |r| r == 20 }
  else
    @rolls.include?(20)
  end
end
reroll(lucky: false) click to toggle source
# File lib/natural_20/die_roll.rb, line 158
def reroll(lucky: false)
  @roller.roll(lucky: lucky)
end
result() click to toggle source

computes the integer result of the dice roll @return [Integer]

# File lib/natural_20/die_roll.rb, line 164
def result
  sum = if @advantage
          @rolls.map(&:max).sum
        elsif @disadvantage
          @rolls.map(&:min).sum
        else
          @rolls.sum
        end

  sum + @modifier
end
to_s() click to toggle source
# File lib/natural_20/die_roll.rb, line 190
def to_s
  rolls = @rolls.map do |r|
    if @advantage
      r.map do |i|
        i == r.max ? color_roll(i).bold : i.to_s.colorize(:gray)
      end.join(' | ')
    elsif @disadvantage
      r.map do |i|
        i == r.min ? color_roll(i).bold : i.to_s.colorize(:gray)
      end.join(' | ')
    else
      color_roll(r)
    end
  end

  if @modifier != 0
    "(#{rolls.join(' + ')}) + #{@modifier}"
  else
    "(#{rolls.join(' + ')})"
  end
end