Class: ShoveAction

Inherits:
Natural20::Action show all
Includes:
Natural20::ActionDamage
Defined in:
lib/natural_20/actions/shove_action.rb

Direct Known Subclasses

PushAction

Instance Attribute Summary collapse

Attributes inherited from Natural20::Action

#action_type, #errors, #result, #session, #source

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Natural20::ActionDamage

#damage_event

Methods inherited from Natural20::Action

#initialize, #label, #name

Constructor Details

This class inherits a constructor from Natural20::Action

Instance Attribute Details

#knock_proneObject

Returns the value of attribute knock_prone.



3
4
5
# File 'lib/natural_20/actions/shove_action.rb', line 3

def knock_prone
  @knock_prone
end

#targetObject

Returns the value of attribute target.



3
4
5
# File 'lib/natural_20/actions/shove_action.rb', line 3

def target
  @target
end

Class Method Details

.apply!(battle, item) ⇒ Object



110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/natural_20/actions/shove_action.rb', line 110

def self.apply!(battle, item)
  case (item[:type])
  when :shove
    if item[:success]
      if item[:knock_prone]
        item[:target].prone!
      elsif item[:shove_loc]
        item[:battle].map.move_to!(item[:target], *item[:shove_loc], battle)
      end

      Natural20::EventManager.received_event(event: :shove_success,
                                             knock_prone: item[:knock_prone],
                                             target: item[:target], source: item[:source],
                                             source_roll: item[:source_roll],
                                             target_roll: item[:target_roll])
    else
      Natural20::EventManager.received_event(event: :shove_failure,
                                             target: item[:target], source: item[:source],
                                             source_roll: item[:source_roll],
                                             target_roll: item[:target_roll])
    end

    battle.entity_state_for(item[:source])[:action] -= 1
  end
end

.build(session, source) ⇒ Object



39
40
41
42
# File 'lib/natural_20/actions/shove_action.rb', line 39

def self.build(session, source)
  action = ShoveAction.new(session, source, :shove)
  action.build_map
end

.can?(entity, battle, _options = {}) ⇒ Boolean

Returns:

  • (Boolean)


5
6
7
# File 'lib/natural_20/actions/shove_action.rb', line 5

def self.can?(entity, battle, _options = {})
  (battle.nil? || entity.total_actions(battle).positive?)
end

Instance Method Details

#build_mapObject



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/natural_20/actions/shove_action.rb', line 18

def build_map
  OpenStruct.new({
                   action: self,
                   param: [
                     {
                       type: :select_target,
                       range: 5,
                       target_types: %i[enemies],
                       num: 1
                     }
                   ],
                   next: lambda { |target|
                     self.target = target
                     OpenStruct.new({
                                      param: nil,
                                      next: -> { self }
                                    })
                   }
                 })
end

#resolve(_session, map, opts = {}) ⇒ Object

Build the attack roll information

Parameters:

Options Hash (opts):



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/natural_20/actions/shove_action.rb', line 49

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

  shove_success = false
  if @target.incapacitated?
    shove_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
    shove_success = strength_roll.result >= contested_roll.result
  end

  shove_loc = nil
  additional_effects = []
  unless knock_prone
    shove_loc = @target.push_from(map, *map.entity_or_object_pos(@source))
    if shove_loc
      trigger_results = map.area_trigger!(@target, shove_loc, false)
      additional_effects += trigger_results
    end
  end
  @result = if shove_success
              [{
                source: @source,
                target: target,
                type: :shove,
                success: true,
                battle: battle,
                shove_loc: shove_loc,
                knock_prone: knock_prone,
                source_roll: strength_roll,
                target_roll: contested_roll
              }] + additional_effects
            else
              [{
                source: @source,
                target: target,
                type: :shove,
                success: false,
                battle: battle,
                knock_prone: knock_prone,
                source_roll: strength_roll,
                target_roll: contested_roll
              }]
            end
end

#to_sObject



14
15
16
# File 'lib/natural_20/actions/shove_action.rb', line 14

def to_s
  @action_type.to_s.humanize
end

#validateObject



9
10
11
12
# File 'lib/natural_20/actions/shove_action.rb', line 9

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