112 lines
No EOL
3.8 KiB
Ruby
112 lines
No EOL
3.8 KiB
Ruby
class CollectionWeapon < ApplicationRecord
|
|
belongs_to :user
|
|
belongs_to :weapon
|
|
belongs_to :awakening, optional: true
|
|
|
|
belongs_to :weapon_key1, class_name: 'WeaponKey', optional: true
|
|
belongs_to :weapon_key2, class_name: 'WeaponKey', optional: true
|
|
belongs_to :weapon_key3, class_name: 'WeaponKey', optional: true
|
|
belongs_to :weapon_key4, class_name: 'WeaponKey', optional: true
|
|
|
|
# Set defaults before validation so database defaults don't cause validation failures
|
|
attribute :awakening_level, :integer, default: 1
|
|
|
|
validates :uncap_level, inclusion: { in: 0..5 }
|
|
validates :transcendence_step, inclusion: { in: 0..10 }
|
|
validates :awakening_level, inclusion: { in: 1..20 }
|
|
|
|
validate :validate_weapon_keys
|
|
validate :validate_ax_skills
|
|
validate :validate_element_change
|
|
validate :validate_awakening_compatibility
|
|
validate :validate_awakening_level
|
|
validate :validate_transcendence_requirements
|
|
|
|
scope :by_weapon, ->(weapon_id) { where(weapon_id: weapon_id) }
|
|
scope :by_series, ->(series_id) { joins(:weapon).where(weapons: { weapon_series_id: series_id }) }
|
|
scope :with_keys, -> { where.not(weapon_key1_id: nil) }
|
|
scope :with_ax, -> { where.not(ax_modifier1: nil) }
|
|
scope :by_element, ->(element) { joins(:weapon).where(weapons: { element: element }) }
|
|
scope :by_rarity, ->(rarity) { joins(:weapon).where(weapons: { rarity: rarity }) }
|
|
scope :transcended, -> { where('transcendence_step > 0') }
|
|
scope :with_awakening, -> { where.not(awakening_id: nil) }
|
|
|
|
def blueprint
|
|
Api::V1::CollectionWeaponBlueprint
|
|
end
|
|
|
|
def weapon_keys
|
|
[weapon_key1, weapon_key2, weapon_key3, weapon_key4].compact
|
|
end
|
|
|
|
private
|
|
|
|
def validate_weapon_keys
|
|
return unless weapon.present?
|
|
|
|
# Validate weapon_key4 is only on Opus/Draconic weapons
|
|
if weapon_key4.present? && !weapon.opus_or_draconic?
|
|
errors.add(:weapon_key4, "can only be set on Opus or Draconic weapons")
|
|
end
|
|
|
|
weapon_keys.each do |key|
|
|
unless weapon.compatible_with_key?(key)
|
|
errors.add(:weapon_keys, "#{key.name_en} is not compatible with this weapon")
|
|
end
|
|
end
|
|
|
|
# Check for duplicate keys
|
|
key_ids = [weapon_key1_id, weapon_key2_id, weapon_key3_id, weapon_key4_id].compact
|
|
if key_ids.length != key_ids.uniq.length
|
|
errors.add(:weapon_keys, "cannot have duplicate keys")
|
|
end
|
|
end
|
|
|
|
def validate_ax_skills
|
|
# Check for incomplete AX skills regardless of weapon.ax
|
|
if (ax_modifier1.present? && ax_strength1.blank?) ||
|
|
(ax_modifier1.blank? && ax_strength1.present?)
|
|
errors.add(:base, "AX skill 1 must have both modifier and strength")
|
|
end
|
|
|
|
if (ax_modifier2.present? && ax_strength2.blank?) ||
|
|
(ax_modifier2.blank? && ax_strength2.present?)
|
|
errors.add(:base, "AX skill 2 must have both modifier and strength")
|
|
end
|
|
end
|
|
|
|
def validate_element_change
|
|
return unless element.present? && weapon.present?
|
|
|
|
unless Weapon.element_changeable?(weapon)
|
|
errors.add(:element, "can only be set on element-changeable weapons")
|
|
end
|
|
end
|
|
|
|
def validate_awakening_compatibility
|
|
return unless awakening.present?
|
|
|
|
unless awakening.object_type == 'Weapon'
|
|
errors.add(:awakening, "must be a weapon awakening")
|
|
end
|
|
end
|
|
|
|
def validate_awakening_level
|
|
if awakening_level.present? && awakening_level > 1 && awakening_id.blank?
|
|
errors.add(:awakening_level, "cannot be set without an awakening")
|
|
end
|
|
end
|
|
|
|
def validate_transcendence_requirements
|
|
return unless transcendence_step.present? && transcendence_step > 0
|
|
|
|
if uncap_level < 5
|
|
errors.add(:transcendence_step, "requires uncap level 5 (current: #{uncap_level})")
|
|
end
|
|
|
|
# Some weapons might not support transcendence
|
|
if weapon.present? && !weapon.transcendence
|
|
errors.add(:transcendence_step, "not available for this weapon") if transcendence_step > 0
|
|
end
|
|
end
|
|
end |