class Natural20::CharacterBuilder
Constants
- ALL_LANGUAGES
Attributes
battle[R]
prompt[R]
session[R]
Public Class Methods
new(prompt, session, battle)
click to toggle source
# File lib/natural_20/cli/character_builder.rb, line 13 def initialize(prompt, session, battle) @prompt = prompt @session = session @battle = battle end
Public Instance Methods
build_character()
click to toggle source
# File lib/natural_20/cli/character_builder.rb, line 19 def build_character @values = { hit_die: 'inherit', classes: {}, ability: {}, skills: [], level: 1, token: ['X'], tools: [] } loop do ability_method = :random @values[:name] = prompt.ask(t('builder.enter_name'), default: @values[:name]) do |q| q.required true q.modify :capitalize end @values[:token] = [prompt.ask(t('builder.token'), default: @values[:name][0])] @values[:color] = prompt.select(t('builder.token_color')) do |q| %i[ red light_red green light_green yellow light_yellow blue light_blue magenta light_magenta cyan light_cyan white light_white ].each do |color| q.choice @values[:token].first.colorize(color), color end end description = prompt.multiline(t('builder.description')) do |q| q.default t('builder.default_description') end @values[:description] = description.is_a?(Array) ? description.join("\n") : description races = session.load_races @values[:race] = prompt.select(t('builder.select_race')) do |q| races.each do |race, details| q.choice details[:label] || race.humanize, race end end race_detail = races[@values[:race]] if race_detail[:subrace] @values[:subrace] = prompt.select(t('builder.select_subrace')) do |q| race_detail[:subrace].each do |subrace, detail| q.choice detail[:label] || t("builder.races.#{subrace}"), subrace end end end subrace_detail = race_detail.dig(:subrace, @values[:subrace]&.to_sym) known_languages = race_detail.fetch(:languages, []) + (subrace_detail&.fetch(:languages, []) || []) language_choice = race_detail.fetch(:language_choice, 0) + (subrace_detail&.fetch(:language_choice, 0) || 0) if language_choice.positive? language_selector(ALL_LANGUAGES - known_languages, min: language_choice, max: language_choice) end race_bonus = race_detail[:attribute_bonus] || {} subrace_bonus = subrace_detail&.fetch(:attribute_bonus, {}) || {} attribute_bonuses = race_bonus.merge!(subrace_bonus) k = prompt.select(t('builder.class')) do |q| session.load_classes.each do |klass, details| q.choice details[:label] || klass.humanize, klass.to_sym end end @values[:classes][k.to_sym] = 1 @class_properties = session.load_class(k) if race_detail[:tool_proficiencies_choice] num_tools_choices = race_detail[:tool_proficiencies_choice] @values[:tools] = prompt.multi_select(t('builder.select_tools_proficiency'), min: num_tools_choices, max: num_tools_choices) do |q| race_detail[:tool_proficiencies].each do |prof| q.choice t("builder.tools.#{prof}"), prof end end end ability_method = prompt.select(t('builder.ability_score_method')) do |q| q.choice t('builder.ability_score.random'), :random q.choice t('builder.ability_score.fixed'), :fixed # q.choice t('builder.ability_score.point_buy'), :point_buy end ability_scores = if ability_method == :random 6.times.map do |index| r = 4.times.map do |_x| die_roll = Natural20::DieRoll.roll('1d6', battle: battle, description: t('dice_roll.ability_score', roll_num: index + 1)) die_roll.result end.sort.reverse puts "#{index + 1}. #{r.join(',')}" r.take(3).sum end.sort.reverse elsif ability_method == :fixed [15, 14, 13, 12, 10, 8] end puts t('builder.assign_ability_scores', scores: ability_scores.join(',')) chosen_score = [] Natural20::Entity::ATTRIBUTE_TYPES_ABBV.each do |type| bonus = attribute_bonuses[type.to_sym] || 0 ability_choice_str = t("builder.#{type}") ability_choice_str += " (+#{bonus})" if bonus.positive? score_index = prompt.select(ability_choice_str) do |q| ability_scores.each_with_index do |score, index| next if chosen_score.include?(index) q.choice score, index end end chosen_score << score_index @values[:ability][type.to_sym] = ability_scores[score_index] + bonus end class_skills_selector send(:"#{k}_builder", @values) @values.merge!(@class_values) @pc = Natural20::PlayerCharacter.new(session, @values) character_sheet(@pc) break if prompt.yes?(t('builder.review')) end session.save_character(@values[:name], @values) @pc end
Protected Instance Methods
class_skills_selector()
click to toggle source
# File lib/natural_20/cli/character_builder.rb, line 187 def class_skills_selector class_skills = @class_properties[:available_skills] num_choices = @class_properties[:available_skills_choices] @values[:skills] += prompt.multi_select(t("builder.#{@values[:classes].keys.first}.select_skill"), min: num_choices, max: num_choices, per_page: 20) do |q| class_skills.each do |skill| q.choice t("builder.skill.#{skill}"), skill end end end
language_selector(languages = ALL_LANGUAGES, min: 1, max: 1)
click to toggle source
# File lib/natural_20/cli/character_builder.rb, line 179 def language_selector(languages = ALL_LANGUAGES, min: 1, max: 1) @values[:languages] = prompt.multi_select(t('builder.select_languages'), min: min, max: max, per_page: 20) do |q| languages.each do |lang| q.choice t("language.#{lang}"), lang end end end
modifier_table(value)
click to toggle source
# File lib/natural_20/cli/character_builder.rb, line 198 def modifier_table(value) mod_table = [[1, 1, -5], [2, 3, -4], [4, 5, -3], [6, 7, -2], [8, 9, -1], [10, 11, 0], [12, 13, 1], [14, 15, 2], [16, 17, 3], [18, 19, 4], [20, 21, 5], [22, 23, 6], [24, 25, 7], [26, 27, 8], [28, 29, 9], [30, 30, 10]] mod_table.each do |row| low, high, mod = row return mod if value.between?(low, high) end end