# frozen_string_literal: true class ArtifactSkill < ApplicationRecord # Enums enum :skill_group, { group_i: 1, group_ii: 2, group_iii: 3 } enum :polarity, { positive: 'positive', negative: 'negative' } # Validations validates :skill_group, presence: true validates :modifier, presence: true, uniqueness: { scope: :skill_group } validates :name_en, presence: true validates :name_jp, presence: true validates :polarity, presence: true # Scopes scope :for_slot, ->(slot) { case slot when 1, 2 then group_i when 3 then group_ii when 4 then group_iii end } # Class methods for caching skill lookups class << self def cached_skills @cached_skills ||= all.index_by { |s| [s.skill_group, s.modifier] } end def cached_by_game_name @game_name_cache ||= begin cache = {} all.each do |skill| # Use game names for matching, fall back to display names if not set en_key = skill.game_name_en.presence || skill.name_en jp_key = skill.game_name_jp.presence || skill.name_jp cache[en_key] = skill cache[jp_key] = skill end cache end end def find_skill(group, modifier) # Convert group number to enum key group_key = case group when 1 then 'group_i' when 2 then 'group_ii' when 3 then 'group_iii' else group.to_s end cached_skills[[group_key, modifier]] end def find_by_game_name(name) cached_by_game_name[name] end def clear_cache! @cached_skills = nil @game_name_cache = nil end end # Calculate the current value of a skill given base strength and skill level # @param base_strength [Numeric] The base strength value of the skill # @param skill_level [Integer] The current skill level (1-5) # @return [Numeric, nil] The calculated value def calculate_value(base_strength, skill_level) return base_strength if growth.nil? base_strength + (growth * (skill_level - 1)) end # Format a value with the appropriate suffix # @param value [Numeric] The value to format # @param locale [Symbol] :en or :jp # @return [String] The formatted value with suffix def format_value(value, locale = :en) suffix = locale == :jp ? suffix_jp : suffix_en "#{value}#{suffix}" end # Check if a strength value is valid for this skill # @param strength [Numeric] The strength value to validate # @return [Boolean] def valid_strength?(strength) return true if base_values.include?(nil) # Unknown values are always valid base_values.include?(strength) end # Get the base strength value for a given quality tier # @param quality [Integer] The quality tier (1-5) # @return [Numeric, nil] The base strength value def strength_for_quality(quality) return nil if base_values.nil? || !base_values.is_a?(Array) || base_values.empty? # Quality 1-5 maps to index 0-4 index = (quality - 1).clamp(0, base_values.size - 1) base_values[index] end end