class GrappleAction

Attributes

target[RW]

Public Class Methods

apply!(battle, item) click to toggle source
# File lib/natural_20/actions/grapple_action.rb, line 97
def self.apply!(battle, item)
  case (item[:type])
  when :grapple
    if item[:success]
      item[:target].grappled_by!(item[:source])
      Natural20::EventManager.received_event(event: :grapple_success,
                                             target: item[:target], source: item[:source],
                                             source_roll: item[:source_roll],
                                             target_roll: item[:target_roll])
    else
      Natural20::EventManager.received_event(event: :grapple_failure,
                                             target: item[:target], source: item[:source],
                                             source_roll: item[:source_roll],
                                             target_roll: item[:target_roll])
    end

    battle.consume(item[:source], :action)
  end
end
build(session, source) click to toggle source
# File lib/natural_20/actions/grapple_action.rb, line 38
def self.build(session, source)
  action = GrappleAction.new(session, source, :grapple)
  action.build_map
end
can?(entity, battle, _options = {}) click to toggle source
# File lib/natural_20/actions/grapple_action.rb, line 4
def self.can?(entity, battle, _options = {})
  (battle.nil? || entity.total_actions(battle).positive?) && !entity.grappling?
end

Public Instance Methods

build_map() click to toggle source
# File lib/natural_20/actions/grapple_action.rb, line 17
def build_map
  OpenStruct.new({
                   action: self,
                   param: [
                     {
                       type: :select_target,
                       range: 5,
                       target_types: %i[enemies allies],
                       num: 1
                     }
                   ],
                   next: lambda { |target|
                     self.target = target
                     OpenStruct.new({
                                      param: nil,
                                      next: -> { self }
                                    })
                   }
                 })
end
resolve(_session, _map, opts = {}) click to toggle source

Build the attack roll information @param session [Natural20::Session] @param map [Natural20::BattleMap] @option opts battle [Natural20::Battle] @option opts target [Natural20::Entity]

# File lib/natural_20/actions/grapple_action.rb, line 48
def resolve(_session, _map, opts = {})
  target = opts[:target] || @target
  battle = opts[:battle]
  raise 'target is a required option for :attack' if target.nil?

  return if (target.size_identifier - @source.size_identifier) > 1

  strength_roll = @source.athletics_check!(battle)
  athletics_stats = (@target.athletics_proficient? ? @target.proficiency_bonus : 0) + @target.str_mod
  acrobatics_stats = (@target.acrobatics_proficient? ? @target.proficiency_bonus : 0) + @target.dex_mod

  grapple_success = false
  if @target.incapacitated? || !battle.opposing?(@source, target)
    grapple_success = true
  else
    contested_roll = if athletics_stats > acrobatics_stats
                       @target.athletics_check!(battle,
                                                description: t('die_roll.contest'))
                     else
                       @target.acrobatics_check!(
                         opts[:battle], description: t('die_roll.contest')
                       )
                     end
    grapple_success = strength_roll.result >= contested_roll.result
  end

  @result = if grapple_success
              [{
                source: @source,
                target: target,
                type: :grapple,
                success: true,
                battle: battle,
                source_roll: strength_roll,
                target_roll: contested_roll
              }]
            else
              [{
                source: @source,
                target: target,
                type: :grapple,
                success: false,
                battle: battle,
                source_roll: strength_roll,
                target_roll: contested_roll
              }]
            end
end
to_s() click to toggle source
# File lib/natural_20/actions/grapple_action.rb, line 8
def to_s
  @action_type.to_s.humanize
end
validate() click to toggle source
# File lib/natural_20/actions/grapple_action.rb, line 12
def validate
  @errors << 'target is a required option for :attack' if target.nil?
  @errors << t('validation.shove.invalid_target_size') if (target.size_identifier - @source.size_identifier) > 1
end