Class: Adventure::Being

Inherits:
Object
  • Object
show all
Defined in:
lib/adventure/being.rb

Overview

Represents any ingame being.

By being, this means any creature, plant, fungus, NPC, Player, or thing that has a monster stat block.

This class implements basic D&D stat management functionalities, as well as battle capabilities.

Constant Summary collapse

ABILITIES =

List of all valid abilities.

%i[str dex con int wis cha].freeze
SKILLS =

List of all valid skills.

%i[acrobatics animal_handling arcana athletics deception history insight intimidation investigation medicine nature perception performance persuasion religion sleight_hand stealth survival].freeze
SIZES =

List of all valid sizes.

%w[Fine Diminutive Tiny Small Medium Large Huge Gargantuan Colossal].freeze
TYPES =

List of canonically valid creature types.

%w[Aberration Animal Beast Celestial Construct Dragon Elemental Fey Fiend Giant Humanoid Ooze Outsider Plant Undead Vermin].freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, **opts) ⇒ Being

Create a new instance of Being.

Parameters:

  • name (String)

    The being's name.

  • opts (Hash)

    A list of parameters.

Options Hash (**opts):

  • :name (String)

    Being's name.

  • :source (String)

    Being's source text, when applicable.

  • :align (String)

    Being's alignment.

  • :cr (Float)

    Being's Challenge Rating.

  • :levels (Hash)

    Being's Hash of levels by, when applicable, class, or Integer of total level.

  • :size (String)

    Being's size.

  • :type (String)

    Being's type.

  • :swarm (Boolean)

    Whether or not this is a swarm of beings.

  • :speed (Hash)

    Being's Hash of speeds, with five elements representing walk, burrow, climb, fly, and swim speeds -- the ones that don't apply set to nil.

  • :senses (Array<String>)

    Being's Array of senses, empty by default.

  • :languages (Array<String>)

    Being's Array of known languages.

  • :rand_abilities (Boolean)

    Whether or not to roll random ability stats -- if set, the initializer ignores any plainly given ability stat.

  • :ability_preferences (Array<Symbol>)

    An array of prioritary abilities, from most importante (index = 0) to least (last index).

  • :ability_min (Integer)

    The minimum value an ability can be, used only when randomly generating ability scores.

  • :ability_max (Integer)

    The maximum value an ability can be, used only when randomly generating ability scores.

  • :str (Integer)

    Being's Strength score, defaults to 10, it unset.

  • :dex (Integer)

    Being's Dexterity score, defaults to 10, it unset.

  • :con (Integer)

    Being's Constitution score, defaults to 10, it unset.

  • :int (Integer)

    Being's Intelligence score, defaults to 10, it unset.

  • :wis (Integer)

    Being's Wisdom score, defaults to 10, it unset.

  • :cha (Integer)

    Being's Charisma score, defaults to 10, it unset.

  • :saves (Array<Symbol>)

    Being's Saving Throw proficiencies, as an Array of Symbol's for each proficient save.

  • :skills (Array<Symbol>)

    Being's Skill proficiencies, as an Array of Symbol's for each proficient skill.

  • :skills_expertise (Array<Symbol>)

    Being's Skill expertises, as an Array of Symbol's for each proficient skill.

  • :ac (Integer)

    Being's Armor Class.

  • :ac_desc (String)

    Being's AC description, if any.

  • :hp (Integer)

    Being's total/maximum Hit Points.

  • :hp_formula (String)

    Being's HP dice formula.

  • :dmg_vulnerabilities (Array<String>)

    Being's Array of Damage Vulnerabilities, if any -- empty by default.

  • :dmg_resistances (Array<String>)

    Being's Array of Damage Resistances, if any -- empty by default.

  • :dmg_immunities (Array<String>)

    Being's Array of Damage Immunities, if any -- empty by default.

  • :condition_immunities (Array<String>)

    Being's Array of Condition Immunities, if any -- empty by default.

  • :spell_header (String)

    Being's Spellcasting block header -- nil if not applicable.

  • :spell_footer (String)

    Being's Spellcasting block footer -- nil if not applicable.

  • :spell_list (Array<Hash>)

    Being's Spellcasting array of spells -- empty by default.

  • :traits (Array<Hash>)

    Being's array of traits.

  • :actions_header (String)

    Being's Actions' header.

  • :actions_list (Array)

    Being's Array of Actions.

  • :bonus_actions_header (String)

    Being's Bonus Actions' header.

  • :bonus_actions_list (Array)

    Being's Array of Bonus Actions.

  • :reactions_header (String)

    Being's Reactions' header.

  • :reactions_list (Array)

    Being's Array of Reactions.

  • :legendary_actions_header (String)

    Being's Legendary Actions' header.

  • :legendary_actions_count (Integer)

    Being's number of Legendary Actions, as Integer.

  • :legendary_actions_list (Array)

    Being's Array of Legendary Actions.

  • :mythic_actions_header (String)

    Being's Mythic Actions' header.

  • :mythic_actions_list (Array)

    Being's Array of Mythic Actions.

  • :inventory (Array)

    Being's Inventory.

  • :purse (Purse)

    Being's Purse.

  • :description (String)

    Being's flavor description/informations.

  • :environment (Array)

    Being's Array of environments.



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/adventure/being.rb', line 222

def initialize(name, **opts)
  @name                     = name.strip
  @source                   = opts.key?(:source) ? opts[:source].strip : nil
  @align                    = opts.key?(:align) ? opts[:align].strip : 'Unaligned'
  if opts.key? :cr
    @cr                     = opts.key?(:cr) ? opts[:cr].to_f : 0.0
    @levels                 = nil
  else
    @cr                     = nil
    @levels                 = opts.key?(:levels) ? opts[:levels].to_a : {}
  end
  @proficiency              = if @levels.nil?
                                proficiency_bonus(@cr.to_i)
                              else
                                proficiency_bonus(@levels)
                              end
  @size                     = opts.key?(:size) ? opts[:size].strip.capitalize : nil
  @size                     = 'Medium' unless SIZES.include? @size
  @type                     = opts.key?(:type) ? opts[:type].strip.capitalize : nil
  @type                     = 'Humanoid' unless TYPES.include? @type
  @subtype                  = opts.key?(:subtype) ? opts[:subtype].strip.capitalize : ''
  @swarm                    = opts.key?(:swarm) ? (opts[:swarm] == true) : false
  @speed                    = if opts.key?(:speed)
                                opts[:speed].to_h
                              else
                                {
                                  walk: 0,
                                  burrow: 0,
                                  climb: 0,
                                  fly: 0,
                                  swim: 0
                                }
                              end
  @senses                   = opts.key?(:senses) ? opts[:senses].to_a : []
  @senses.map!(&:to_s)
  if opts.key? :rand_abilities
    prefs                   = opts.key?(:ability_preferences) ? opts[:ability_preferences].to_a : nil
    min                     = opts.key?(:ability_min) ? opts[:ability_min].to_i : 1
    max                     = opts.key?(:ability_max) ? opts[:ability_max].to_i : 20
    roll_for_abilities(prefs: prefs, min: min, max: max)
  else
    @str                    = opts.key?(:str) ? opts[:@str].to_i : 10
    @dex                    = opts.key?(:dex) ? opts[:@dex].to_i : 10
    @con                    = opts.key?(:con) ? opts[:@con].to_i : 10
    @int                    = opts.key?(:int) ? opts[:@int].to_i : 10
    @wis                    = opts.key?(:wis) ? opts[:@wis].to_i : 10
    @cha                    = opts.key?(:cha) ? opts[:@cha].to_i : 10
  end
  @languages = opts.key?(:languages) ? opts[:languages].to_a : []
  @languages.map!(&:to_s)
  @saves = if opts.key? :saves
             opts[:saves].to_a.uniq
           else
             []
           end
  @saves.select! { |save| ABILITIES.include? save }
  @skills                   = if opts.key? :skills
                                opts[:skills].to_a.uniq
                              else
                                []
                              end
  @skills.select! { |skill| SKILLS.include? skill }
  @skills_expertise         = if opts.key? :skills_expertise
                                opts[:skills_expertise].to_a.uniq
                              else
                                []
                              end
  @skills_expertise.select! { |skill| SKILLS.include? skill }
  @ac                       = opts.key?(:ac) ? opts[:ac].to_i : 0
  @ac_desc                  = opts.key?(:ac_desc) ? opts[:ac_desc].strip : nil
  @hp                       = opts.key?(:hp) ? opts[:hp].to_i : 0
  @current_hp               = @hp
  @hp_formula               = opts.key?(:hp_formula) ? opts[:hp_formula].strip : nil
  @dmg_vulnerabilities      = opts.key?(:dmg_vulnerabilities) ? opts[:dmg_vulnerabilities].to_a : []
  @dmg_resistances          = opts.key?(:dmg_resistances) ? opts[:dmg_resistances].to_a : []
  @dmg_immunities           = opts.key?(:dmg_immunities) ? opts[:dmg_immunities].to_a : []
  @condition_immunities     = opts.key?(:condition_immunities) ? opts[:condition_immunities].to_a : []
  @spell_header             = opts.key?(:spell_header) ? opts[:spell_header].strip : ''
  @spell_footer             = opts.key?(:spell_footer) ? opts[:spell_footer].strip : ''
  @spell_list               = opts.key?(:spell_list) ? opts[:spell_list].to_a : []
  @traits                   = opts.key?(:traits) ? opts[:traits].to_a : []
  @actions_header           = opts.key?(:actions_header) ? opts[:actions_header].strip : ''
  @actions_list             = opts.key?(:actions_list) ? opts[:actions_list].to_a : []
  @bonus_actions_header     = opts.key?(:bonus_actions_header) ? opts[:bonus_actions_header].strip : ''
  @bonus_actions_list       = opts.key?(:bonus_actions_list) ? opts[:bonus_actions_list].to_a : []
  @reactions_header         = opts.key?(:reactions_header) ? opts[:reactions_header].strip : ''
  @reactions_list           = opts.key?(:reactions_list) ? opts[:reactions_list].to_a : []
  @legendary_actions_header = opts.key?(:legendary_actions_header) ? opts[:legendary_actions_header].strip : ''
  @legendary_actions_count  = opts.key?(:legendary_actions_count) ? opts[:legendary_actions_count].to_i : 0
  @legendary_actions_list   = opts.key?(:legendary_actions_list) ? opts[:legendary_actions_list].to_a : []
  @mythic_actions_header    = opts.key?(:mythic_actions_header) ? opts[:mythic_actions_header].strip : ''
  @mythic_actions_list      = opts.key?(:mythic_actions_list) ? opts[:mythic_actions_list].to_a : []
  @inventory                = opts.key?(:inventory) ? opts[:inventory] : []
  @inventory                = Inventory.new unless @inventory.is_a? Inventory
  @purse                    = opts.key?(:purse) ? opts[:purse] : []
  @purse                    = Purse.new unless @purse.is_a? Purse
  @description              = opts.key?(:description) ? opts[:description].strip : ''
  @environment              = opts.key?(:environment) ? opts[:environment].to_a : []
end

Instance Attribute Details

#acObject (readonly)

Returns the value of attribute ac.



84
85
86
# File 'lib/adventure/being.rb', line 84

def ac
  @ac
end

#ac_descObject (readonly)

Returns the value of attribute ac_desc.



87
88
89
# File 'lib/adventure/being.rb', line 87

def ac_desc
  @ac_desc
end

#actions_headerObject (readonly)

Returns the value of attribute actions_header.



123
124
125
# File 'lib/adventure/being.rb', line 123

def actions_header
  @actions_header
end

#actions_listObject (readonly)

Returns the value of attribute actions_list.



126
127
128
# File 'lib/adventure/being.rb', line 126

def actions_list
  @actions_list
end

#alignObject (readonly)

Returns the value of attribute align.



30
31
32
# File 'lib/adventure/being.rb', line 30

def align
  @align
end

#bonus_actions_headerObject (readonly)

Returns the value of attribute bonus_actions_header.



129
130
131
# File 'lib/adventure/being.rb', line 129

def bonus_actions_header
  @bonus_actions_header
end

#bonus_actions_listObject (readonly)

Returns the value of attribute bonus_actions_list.



132
133
134
# File 'lib/adventure/being.rb', line 132

def bonus_actions_list
  @bonus_actions_list
end

#chaObject (readonly)

Returns the value of attribute cha.



78
79
80
# File 'lib/adventure/being.rb', line 78

def cha
  @cha
end

#conObject (readonly)

Returns the value of attribute con.



69
70
71
# File 'lib/adventure/being.rb', line 69

def con
  @con
end

#condition_immunitiesObject (readonly)

Returns the value of attribute condition_immunities.



108
109
110
# File 'lib/adventure/being.rb', line 108

def condition_immunities
  @condition_immunities
end

#crObject (readonly)

Returns the value of attribute cr.



33
34
35
# File 'lib/adventure/being.rb', line 33

def cr
  @cr
end

#current_hpObject (readonly)

Returns the value of attribute current_hp.



93
94
95
# File 'lib/adventure/being.rb', line 93

def current_hp
  @current_hp
end

#descriptionObject (readonly)

Returns the value of attribute description.



162
163
164
# File 'lib/adventure/being.rb', line 162

def description
  @description
end

#dexObject (readonly)

Returns the value of attribute dex.



66
67
68
# File 'lib/adventure/being.rb', line 66

def dex
  @dex
end

#dmg_immunitiesObject (readonly)

Returns the value of attribute dmg_immunities.



105
106
107
# File 'lib/adventure/being.rb', line 105

def dmg_immunities
  @dmg_immunities
end

#dmg_resistancesObject (readonly)

Returns the value of attribute dmg_resistances.



102
103
104
# File 'lib/adventure/being.rb', line 102

def dmg_resistances
  @dmg_resistances
end

#dmg_vulnerabilitiesObject (readonly)

Returns the value of attribute dmg_vulnerabilities.



99
100
101
# File 'lib/adventure/being.rb', line 99

def dmg_vulnerabilities
  @dmg_vulnerabilities
end

#environmentObject (readonly)

Returns the value of attribute environment.



165
166
167
# File 'lib/adventure/being.rb', line 165

def environment
  @environment
end

#hpObject (readonly)

Returns the value of attribute hp.



90
91
92
# File 'lib/adventure/being.rb', line 90

def hp
  @hp
end

#hp_formulaObject (readonly)

Returns the value of attribute hp_formula.



96
97
98
# File 'lib/adventure/being.rb', line 96

def hp_formula
  @hp_formula
end

#intObject (readonly)

Returns the value of attribute int.



72
73
74
# File 'lib/adventure/being.rb', line 72

def int
  @int
end

#inventoryObject (readonly)

Returns the value of attribute inventory.



156
157
158
# File 'lib/adventure/being.rb', line 156

def inventory
  @inventory
end

#languagesObject (readonly)

Returns the value of attribute languages.



60
61
62
# File 'lib/adventure/being.rb', line 60

def languages
  @languages
end

#legendary_actions_countObject (readonly)

Returns the value of attribute legendary_actions_count.



144
145
146
# File 'lib/adventure/being.rb', line 144

def legendary_actions_count
  @legendary_actions_count
end

#legendary_actions_headerObject (readonly)

Returns the value of attribute legendary_actions_header.



141
142
143
# File 'lib/adventure/being.rb', line 141

def legendary_actions_header
  @legendary_actions_header
end

#legendary_actions_listObject (readonly)

Returns the value of attribute legendary_actions_list.



147
148
149
# File 'lib/adventure/being.rb', line 147

def legendary_actions_list
  @legendary_actions_list
end

#levelsObject (readonly)

Returns the value of attribute levels.



39
40
41
# File 'lib/adventure/being.rb', line 39

def levels
  @levels
end

#mythic_actions_headerObject (readonly)

Returns the value of attribute mythic_actions_header.



150
151
152
# File 'lib/adventure/being.rb', line 150

def mythic_actions_header
  @mythic_actions_header
end

#mythic_actions_listObject (readonly)

Returns the value of attribute mythic_actions_list.



153
154
155
# File 'lib/adventure/being.rb', line 153

def mythic_actions_list
  @mythic_actions_list
end

#nameObject (readonly)

Returns the value of attribute name.



24
25
26
# File 'lib/adventure/being.rb', line 24

def name
  @name
end

#passive_perceptionObject (readonly)

Returns the value of attribute passive_perception.



81
82
83
# File 'lib/adventure/being.rb', line 81

def passive_perception
  @passive_perception
end

#proficiencyObject (readonly)

Returns the value of attribute proficiency.



36
37
38
# File 'lib/adventure/being.rb', line 36

def proficiency
  @proficiency
end

#purseObject (readonly)

Returns the value of attribute purse.



159
160
161
# File 'lib/adventure/being.rb', line 159

def purse
  @purse
end

#reactions_headerObject (readonly)

Returns the value of attribute reactions_header.



135
136
137
# File 'lib/adventure/being.rb', line 135

def reactions_header
  @reactions_header
end

#reactions_listObject (readonly)

Returns the value of attribute reactions_list.



138
139
140
# File 'lib/adventure/being.rb', line 138

def reactions_list
  @reactions_list
end

#sensesObject (readonly)

Returns the value of attribute senses.



57
58
59
# File 'lib/adventure/being.rb', line 57

def senses
  @senses
end

#sizeObject (readonly)

Returns the value of attribute size.



42
43
44
# File 'lib/adventure/being.rb', line 42

def size
  @size
end

#sourceObject (readonly)

Returns the value of attribute source.



27
28
29
# File 'lib/adventure/being.rb', line 27

def source
  @source
end

#speedObject (readonly)

Returns the value of attribute speed.



54
55
56
# File 'lib/adventure/being.rb', line 54

def speed
  @speed
end

Returns the value of attribute spell_footer.



114
115
116
# File 'lib/adventure/being.rb', line 114

def spell_footer
  @spell_footer
end

#spell_headerObject (readonly)

Returns the value of attribute spell_header.



111
112
113
# File 'lib/adventure/being.rb', line 111

def spell_header
  @spell_header
end

#spell_listObject (readonly)

Returns the value of attribute spell_list.



117
118
119
# File 'lib/adventure/being.rb', line 117

def spell_list
  @spell_list
end

#strObject (readonly)

Returns the value of attribute str.



63
64
65
# File 'lib/adventure/being.rb', line 63

def str
  @str
end

#subtypeObject (readonly)

Returns the value of attribute subtype.



48
49
50
# File 'lib/adventure/being.rb', line 48

def subtype
  @subtype
end

#swarmObject (readonly)

Returns the value of attribute swarm.



51
52
53
# File 'lib/adventure/being.rb', line 51

def swarm
  @swarm
end

#traitsObject (readonly)

Returns the value of attribute traits.



120
121
122
# File 'lib/adventure/being.rb', line 120

def traits
  @traits
end

#typeObject (readonly)

Returns the value of attribute type.



45
46
47
# File 'lib/adventure/being.rb', line 45

def type
  @type
end

#wisObject (readonly)

Returns the value of attribute wis.



75
76
77
# File 'lib/adventure/being.rb', line 75

def wis
  @wis
end

Instance Method Details

#alive?Boolean

Whether this Being is alive or not.

Uses the current HP as parameter to define life status.

Returns:

  • (Boolean)

    true if current HP is greater than 0, false otherwise.



552
553
554
# File 'lib/adventure/being.rb', line 552

def alive?
  @current_hp.positive?
end

#damage(amount) ⇒ Integer

Deal some damage to this Being, modifying the current HP accordingly.

If the damage is greater than the current HP, the latter is normalized to 0, instead.

Parameters:

  • amount (Integer)

    The amount of damage to be dealt, negative values are accepted, but are not counted as healing --- use #heal instead.

Returns:

  • (Integer)

    The new current HP.



513
514
515
516
517
518
# File 'lib/adventure/being.rb', line 513

def damage(amount)
  amount       = amount.to_i.abs
  @current_hp -= amount
  @current_hp  = [@current_hp, 0].max
  @current_hp
end

#dead?Boolean

Whether this Being is dead or not.

Uses the current HP as parameter to define dead status.

Returns:

  • (Boolean)

    true if current HP is 0, false otherwise.



542
543
544
# File 'lib/adventure/being.rb', line 542

def dead?
  @current_hp.zero?
end

#heal(amount) ⇒ Integer

Heal this Being by the given amount, modifying the current HP accordingly.

If the new current HP is greater than the maximun HP, the former is normalized to the maximun HP, instead.

Parameters:

  • amount (Integer)

    The amount to heal the Being by, negative values are accepted, but are not counted as damage --- use #damage instead.

Returns:

  • (Integer)

    The new current HP.



529
530
531
532
533
534
# File 'lib/adventure/being.rb', line 529

def heal(amount)
  amount       = amount.to_i.abs
  @current_hp += amount
  @current_hp  = [@current_hp, @hp].min
  @current_hp
end

#modifier(value) ⇒ Integer (private)

Get the modifier for the given attribute's value.

Modifier = (Score - 10) / 2, rounded down.

Parameters:

  • value (Numeric)

    A value to have its modifier calculated.

Returns:

  • (Integer)

    The corresponding modifier, according to the formula above.



630
631
632
# File 'lib/adventure/being.rb', line 630

def modifier(value)
  ((value.to_f - 10.0) / 2.0).floor
end

#proficiency_bonus(levels) ⇒ Integer (private)

Calculate proficiency bonus according to Someone_Evil's formula.

Parameters:

  • levels (Integer, Hash)

    Either the total level or a Hash of levels.

Returns:

  • (Integer)

    An Integer representing the corresponding Proficiency Bonus.



562
563
564
565
566
567
568
569
570
571
572
573
574
575
# File 'lib/adventure/being.rb', line 562

def proficiency_bonus(levels)
  total_level = if levels.is_a? Numeric
                  levels.to_i
                elsif levels.is_a? Hash
                  levels.values.sum
                else
                  0
                end
  if total_level.positive?
    (1.0 + (total_level.to_f / 4.0)).ceil
  else
    2
  end
end

#roll_for_abilities(**opts) ⇒ Object (private)

Set ability scores randomly

Parameters:

  • opts (Hash)

    A Hash of options to be used.

Options Hash (**opts):

  • :prefs (Array<Symbol>)

    An Array of Symbol's representing the order to prioritize abilities.

  • :min (Integer)

    The minimum value an ability can have, defaults to 1.

  • :max (Integer)

    The minimum value an ability can have, defaults to 20.



583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
# File 'lib/adventure/being.rb', line 583

def roll_for_abilities(**opts)
  # Get minimum value, or set it to `1`.
  min       = opts.key?(:min) ? opts[:min].to_i - 10 : -9
  # Get maximum value, or set it to `20`.
  max       = opts.key?(:max) ? opts[:max].to_i - 10 : 10
  # Set min and max as range
  range     = Range.new min, max

  # Get preferences and parse their uniquiness, or shuffle de default list above.
  prefs = if opts.key? :prefs
            opts[:prefs].to_a.uniq
          else
            ABILITIES.shuffle
          end
  # Filter invalid abilities
  prefs.select! { |x| ABILITIES.include? x }
  # Add randomly any missing abilities, if applicable
  missing_abilities = ABILITIES - prefs
  prefs += missing_abilities.shuffle if missing_abilities.length.positive?

  # Roll scores
  scores = Array.new(6)
  scores.map! do
    10 + rand(range)
  end
  # Order from biggest to lowest
  scores.sort!.reverse!

  # Assign scores to abilities
  prefs.each_with_index do |a, i|
    case a
    when :str then @str = scores[i]
    when :dex then @dex = scores[i]
    when :con then @con = scores[i]
    when :int then @int = scores[i]
    when :wis then @wis = scores[i]
    when :cha then @cha = scores[i]
    end
  end
end

#roll_for_save(ability) ⇒ Integer

Roll for a Saving Throw for the given ability.

Parameters:

  • ability (Symbol, String)

    The ability abbreviation as either a String or a Symbol.

Returns:

  • (Integer)

    The roll's result added to the corresponding save modifier.

Raises:

  • (StandardError)

    If the given ability is not a valid ability abbreviation.

See Also:



398
399
400
401
402
403
# File 'lib/adventure/being.rb', line 398

def roll_for_save(ability)
  mod = save(ability)
  roll = rand(1..20)

  roll + mod
end

#roll_for_skill(skill) ⇒ Integer

Roll for the given Skill.

The possible skills are:

  • :acrobatics;
  • :animal_handling;
  • :arcana;
  • :athletics;
  • :deception;
  • :history;
  • :insight;
  • :intimidation;
  • :investigation;
  • :medicine;
  • :nature;
  • :perception;
  • :performance;
  • :persuasion;
  • :religion;
  • :sleight_hand;
  • :stealth; and
  • :survival.

This method also accepts a String of the full name of the skill, as presented in the official character sheet.

Parameters:

  • skill (Symbol, String)

    The skill as either a String or a Symbol.

Returns:

  • (Integer)

    The roll's result added to the corresponding skill modifier, either plain, proficiency, or expertise.

Raises:

  • (StandardError)

    If the given skill is not a valid one.

See Also:



498
499
500
501
502
503
# File 'lib/adventure/being.rb', line 498

def roll_for_skill(skill)
  mod = skill(skill)
  roll = rand(1..20)

  roll + mod
end

#save(ability) ⇒ Integer

Get the Saving Throw modifier for the given ability.

Parameters:

  • ability (Symbol, String)

    The ability abbreviation as either a String or a Symbol.

Returns:

  • (Integer)

    The corresponding save modifier.

Raises:

  • (StandardError)

    If the given ability is not a valid ability abbreviation.

See Also:



371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
# File 'lib/adventure/being.rb', line 371

def save(ability)
  # Raise error if ability is not valid.
  raise StandardError, 'Invalid ability.' unless ABILITIES.include?(ability.to_sym)

  # Parse ability to valid string
  ability = ability[0..2].downcase.to_swm
  # Check for Proficiency in the Saving Throw
  mod = @saves.include?(ability) ? @proficiency : 0

  case ability
  when :str then modifier(@str) + mod
  when :dex then modifier(@dex) + mod
  when :con then modifier(@con) + mod
  when :int then modifier(@int) + mod
  when :wis then modifier(@wis) + mod
  when :cha then modifier(@cha) + mod
  else
    0
  end
end

#skill(skill) ⇒ Integer

Get the Skill modifier for the given skill.

The possible skills are:

  • :acrobatics;
  • :animal_handling;
  • :arcana;
  • :athletics;
  • :deception;
  • :history;
  • :insight;
  • :intimidation;
  • :investigation;
  • :medicine;
  • :nature;
  • :perception;
  • :performance;
  • :persuasion;
  • :religion;
  • :sleight_hand;
  • :stealth; and
  • :survival.

This method also accepts a String of the full name of the skill, as presented in the official character sheet.

Parameters:

  • skill (Symbol, String)

    The skill as either a String or a Symbol.

Returns:

  • (Integer)

    The corresponding skill modifier.

Raises:

  • (StandardError)

    If the given skill is not a valid one.

See Also:



436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/adventure/being.rb', line 436

def skill(skill)
  # Raise error if skill is not valid.
  raise StandardError, 'Invalid skill.' unless SKILLS.include?(skill.to_sym)

  # Parse skill to valid string
  skill.gsub!(' of', '').gsub!(/ /, '_').downcase! unless skill.is_a? Symbol
  # Check for Proficiency or Expertise in the skill
  mod = if @skills.include? skill.to_sym
          @proficiency
        elsif @skills_expertise.include? skill.to_sym
          @proficiency * 2
        else
          0
        end

  case skill.to_sym
  when :athletics
    modifier(@str) + mod
  when :acrobatics, :sleight_hand, :stealth
    modifier(@dex) + mod
  when :arcana, :history, :investigation, :nature, :religion
    modifier(@int) + mod
  when :animal_handling, :insight, :medicine, :perception, :survival
    modifier(@wis) + mod
  when :deception, :intimidation, :performance, :persuasion
    modifier(@cha) + mod
  else
    0
  end
end

#to_aArray

Get an Array of the being's abilities in the classical order: Strength, Dexterity, Constitution, Intelligence, Wisdom, and Charisma.

Returns:

  • (Array)

    An Array of the being's abilities: [STR, DEX, CON, INT, WIS, CHA].



346
347
348
# File 'lib/adventure/being.rb', line 346

def to_a
  [@str, @dex, @con, @int, @wis, @cha]
end

#to_hHash

Get a Hash of the being's abilities, indexed by each ability abbreviation.

Returns:

  • (Hash)

    A Hash of the being's abilities.



354
355
356
357
358
359
360
361
362
363
# File 'lib/adventure/being.rb', line 354

def to_h
  {
    str: @str,
    dex: @dex,
    con: @con,
    int: @int,
    wis: @wis,
    cha: @cha
  }
end

#to_iInteger

Get either the being's Challenge Rating or the sum of its levels.

Returns:

  • (Integer)

    Either the being's CR or the sum of its levels.



333
334
335
336
337
338
339
# File 'lib/adventure/being.rb', line 333

def to_i
  if @levels.nil?
    @cr
  else
    @levels.values.sum
  end
end

#to_sString

Get the being's name.

Returns:

  • (String)

    The being's name.



325
326
327
# File 'lib/adventure/being.rb', line 325

def to_s
  @name
end