Class: Wayfinder::Character

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

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source_data = {}) ⇒ Character

Returns a new instance of Character.



22
23
24
# File 'lib/wayfinder.rb', line 22

def initialize(source_data = {})
  self.source_data = source_data
end

Instance Attribute Details

#source_dataObject

:source_data must be a hash with the following keys, each containing the data of its corresponding yaml file.

* main         - contains hp, base attack bonus, saving throws, xp, name,
                 basic stats, str, dex, con, wis, int and cha.

* modifiers    - contains descriptions of items, feats, magical effects, or
                 any other thing that modifies character attributes.

* skills       - skills contain data on the ranks and associated stats for
                 each given skill.


20
21
22
# File 'lib/wayfinder.rb', line 20

def source_data
  @source_data
end

Instance Method Details

#acObject



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

def ac
  10 + dexterity_modifier + modifier_for('ac')
end

#active_stackObject

Returns an array of items in the modifier stack marked with ‘active: true’



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

def active_stack
  source_data.modifiers.select { |item| item.fetch('active', true) }
end

#alignmentObject



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

def alignment
  source_data.main.alignment
end

#babObject



133
134
135
# File 'lib/wayfinder.rb', line 133

def bab
  source_data.main.bab
end

#base_ability_scoresObject



37
38
39
# File 'lib/wayfinder.rb', line 37

def base_ability_scores
  source_data.main.ability_scores
end

#base_saving_throwsObject



41
42
43
# File 'lib/wayfinder.rb', line 41

def base_saving_throws
  source_data.main.saving_throws
end

#cmbObject



164
165
166
# File 'lib/wayfinder.rb', line 164

def cmb
  10 + bab + strength_modifier + modifier_for('cmd')
end

#cmdObject



160
161
162
# File 'lib/wayfinder.rb', line 160

def cmd
  10 + bab + strength_modifier + dexterity_modifier + modifier_for('cmd')
end

#current_hpObject



121
122
123
# File 'lib/wayfinder.rb', line 121

def current_hp
  hp - received_damage
end

#damageObject



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

def damage
  strength_modifier + modifier_for('damage')
end

#damage_reductionObject



168
169
170
# File 'lib/wayfinder.rb', line 168

def damage_reduction
  0 + modifier_for('damage_reduction')
end

#fortitudeObject



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

def fortitude
  base_saving_throws.fortitude + constitution_modifier + modifier_for('fortitude')
end

#full_attackObject



145
146
147
148
149
150
151
152
153
154
# File 'lib/wayfinder.rb', line 145

def full_attack
  attack_babs = [bab]

  ## Fuck yeah I used a while in ruby, fuck you, fuck everything, EVERYTHING.
  while attack_babs.last - 5 >= 1
    attack_babs << attack_babs.last - 5
  end

  attack_babs.map { |attack| to_hit(attack) }
end

#hpObject



113
114
115
# File 'lib/wayfinder.rb', line 113

def hp
  source_data.main.hp + modifier_for('hp')
end

#initiativeObject



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

def initiative
  dexterity_modifier + modifier_for('initiative')
end

#modifier_for(attribute) ⇒ Object

Outputs the final numeric modifier for the specified attribute.



91
92
93
94
95
96
97
98
99
# File 'lib/wayfinder.rb', line 91

def modifier_for(attribute)
  modifier = 0

  stack_for(attribute).each do |mod|
    modifier += mod.fetch('modifiers', {}).fetch(attribute, 0)
  end

  modifier
end

#nameObject



101
102
103
# File 'lib/wayfinder.rb', line 101

def name
  source_data.main.name
end

#received_damageObject



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

def received_damage
  source_data.main.received_damage
end

#reflexObject



49
50
51
# File 'lib/wayfinder.rb', line 49

def reflex
  base_saving_throws.reflex + dexterity_modifier + modifier_for('reflex')
end

#saving_throwsObject



57
58
59
60
61
62
63
# File 'lib/wayfinder.rb', line 57

def saving_throws
  {
    fortitude:  fortitude,
    reflex:     reflex,
    will:       will
  }
end

#skill(skill_name) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/wayfinder.rb', line 172

def skill(skill_name)
  skill = source_data.skills.fetch(skill_name, {})

  computed_score = skill.fetch('ranks', 0) +
                   self.send("#{ skill.stat }_modifier") +
                   modifier_for(skill_name) +
                   modifier_for('all_skills')

  computed_score += 3 if skill['class']

  computed_score
end

#skillsObject



185
186
187
188
189
# File 'lib/wayfinder.rb', line 185

def skills
  source_data.skills.map do |name, _|
    [name, skill(name)]
  end.to_h
end

#speedObject



125
126
127
# File 'lib/wayfinder.rb', line 125

def speed
  30 + modifier_for('speed')
end

#stack_for(attribute) ⇒ Object

Returns an array of object who affect the specified attribute



71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/wayfinder.rb', line 71

def stack_for(attribute)
  related_stack = active_stack.select { |item|
    item.fetch('modifiers', {}).keys.include?(attribute)
  }.group_by { |item| item['type'] }

  # Start by adding all modifiers with no type, or initializing at []
  applicable_stack = related_stack.delete(nil) || []

  # Then for each of the remaining modifiers by group, pick only the
  # biggest one.
  related_stack.each { |_, mods|
    applicable_stack << mods.sort_by { |m|
                          m.modifiers[attribute]
                        }.last
  }

  applicable_stack
end

#to_hit(base_attack = self.bab) ⇒ Object



137
138
139
# File 'lib/wayfinder.rb', line 137

def to_hit(base_attack = self.bab)
  base_attack + strength_modifier + modifier_for('to_hit')
end

#willObject



53
54
55
# File 'lib/wayfinder.rb', line 53

def will
  base_saving_throws.will + wisdom_modifier + modifier_for('will')
end

#xpObject



109
110
111
# File 'lib/wayfinder.rb', line 109

def xp
  source_data.main.xp
end