Add sigs and docs to transformers
This commit is contained in:
parent
0d5d4d5f59
commit
144d860408
7 changed files with 221 additions and 11 deletions
|
|
@ -11,7 +11,11 @@ module Granblue
|
|||
end
|
||||
end
|
||||
|
||||
# Base class for transforming game data into standardized format
|
||||
# @abstract
|
||||
class BaseTransformer
|
||||
# Mapping of game element IDs to internal element IDs
|
||||
# @return [Hash<Integer, Integer?>]
|
||||
ELEMENT_MAPPING = {
|
||||
0 => nil,
|
||||
1 => 4, # Wind -> Earth
|
||||
|
|
@ -22,6 +26,12 @@ module Granblue
|
|||
6 => 5 # Light -> Dark
|
||||
}.freeze
|
||||
|
||||
# Initialize a new transformer
|
||||
# @param data [Object] Raw game data to transform
|
||||
# @param options [Hash<Symbol, Object>] Optional configuration settings
|
||||
# @option options [String] :language ('en') Language code for transformations
|
||||
# @option options [Boolean] :debug (false) Enable debug logging
|
||||
# @return [void]
|
||||
def initialize(data, options = {})
|
||||
@data = data
|
||||
@options = options
|
||||
|
|
@ -30,6 +40,9 @@ module Granblue
|
|||
validate_data
|
||||
end
|
||||
|
||||
# Transform the raw data into standardized format
|
||||
# @abstract Subclasses must implement this method
|
||||
# @return [Object] Transformed data
|
||||
def transform
|
||||
raise NotImplementedError, "#{self.class} must implement #transform"
|
||||
end
|
||||
|
|
@ -38,6 +51,8 @@ module Granblue
|
|||
|
||||
attr_reader :data, :options, :language
|
||||
|
||||
# Validate the input data structure
|
||||
# @return [Boolean] true if valid, false otherwise
|
||||
def validate_data
|
||||
Rails.logger.info "[TRANSFORM] Validating data: #{data.inspect[0..100]}..."
|
||||
|
||||
|
|
@ -55,6 +70,9 @@ module Granblue
|
|||
true
|
||||
end
|
||||
|
||||
# Extract master and parameter data from an object
|
||||
# @param obj [Hash<String, Object>] Object containing master/param data
|
||||
# @return [Array<(Hash?, Hash?)>] Array containing master and param data
|
||||
def get_master_param(obj)
|
||||
return [nil, nil] unless obj.is_a?(Hash)
|
||||
|
||||
|
|
@ -65,6 +83,9 @@ module Granblue
|
|||
[master, param]
|
||||
end
|
||||
|
||||
# Log a debug message if debug mode is enabled
|
||||
# @param message [String] Message to log
|
||||
# @return [void]
|
||||
def log_debug(message)
|
||||
return unless options[:debug]
|
||||
Rails.logger.debug "[TRANSFORM-DEBUG] #{self.class.name}: #{message}"
|
||||
|
|
|
|||
|
|
@ -1,16 +1,41 @@
|
|||
module Granblue
|
||||
module Transformers
|
||||
# Transforms raw game character data into standardized format for database import.
|
||||
# Handles character stats, uncap levels, transcendence, and perpetuity rings.
|
||||
#
|
||||
# @example Transforming character data
|
||||
# data = { "master" => { "name" => "Katalina", "id" => "3040001000" },
|
||||
# "param" => { "evolution" => 3, "phase" => 1 } }
|
||||
# transformer = CharacterTransformer.new(data)
|
||||
# result = transformer.transform
|
||||
# # => [{ name: "Katalina", id: "3040001000", uncap: 3, transcend: 1 }]
|
||||
#
|
||||
# @note Expects data with "master" and "param" nested objects for each character
|
||||
# @note Will filter out characters with missing or invalid required attributes
|
||||
#
|
||||
# @see BaseTransformer For base transformation functionality
|
||||
class CharacterTransformer < BaseTransformer
|
||||
# Transforms raw game character data into a standardized format
|
||||
# @return [Array<Hash>] Array of character hashes with standardized attributes:
|
||||
# @option character [String] :name Character's name
|
||||
# @option character [String] :id Character's ID
|
||||
# @option character [Integer] :uncap Character's uncap level
|
||||
# @option character [Boolean] :ringed Whether character has perpetuity rings
|
||||
# @option character [Integer] :transcend Character's transcendence phase level
|
||||
def transform
|
||||
# Log start of transformation process
|
||||
Rails.logger.info "[TRANSFORM] Starting CharacterTransformer#transform"
|
||||
|
||||
# Validate that the input data is a Hash
|
||||
unless data.is_a?(Hash)
|
||||
Rails.logger.error "[TRANSFORM] Invalid character data structure"
|
||||
return []
|
||||
end
|
||||
|
||||
characters = []
|
||||
# Iterate through each character data entry
|
||||
data.each_value do |char_data|
|
||||
# Skip entries missing required master/param data
|
||||
next unless char_data['master'] && char_data['param']
|
||||
|
||||
master = char_data['master']
|
||||
|
|
@ -18,27 +43,29 @@ module Granblue
|
|||
|
||||
Rails.logger.debug "[TRANSFORM] Processing character: #{master['name']}"
|
||||
|
||||
# Build base character hash with required attributes
|
||||
character = {
|
||||
name: master['name'],
|
||||
id: master['id'],
|
||||
uncap: param['evolution'].to_i
|
||||
name: master['name'], # Character's display name
|
||||
id: master['id'], # Unique identifier
|
||||
uncap: param['evolution'].to_i # Current uncap level
|
||||
}
|
||||
|
||||
Rails.logger.debug "[TRANSFORM] Base character data: #{character}"
|
||||
|
||||
# Add perpetuity (rings) if present
|
||||
# Add perpetuity ring status if present
|
||||
if param['has_npcaugment_constant']
|
||||
character[:ringed] = true
|
||||
Rails.logger.debug "[TRANSFORM] Character is ringed"
|
||||
end
|
||||
|
||||
# Add transcendence if present
|
||||
# Add transcendence level if present (stored as 'phase' in raw data)
|
||||
phase = param['phase'].to_i
|
||||
if phase && phase.positive?
|
||||
if phase&.positive?
|
||||
character[:transcend] = phase
|
||||
Rails.logger.debug "[TRANSFORM] Character has transcendence: #{phase}"
|
||||
end
|
||||
|
||||
# Only add characters with valid IDs to result set
|
||||
characters << character unless master['id'].nil?
|
||||
Rails.logger.info "[TRANSFORM] Successfully processed character #{character[:name]}"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,18 +2,45 @@
|
|||
|
||||
module Granblue
|
||||
module Transformers
|
||||
# Transforms raw game summon data into standardized format for database import.
|
||||
# Handles summon stats, uncap levels, transcendence, and quick summon status.
|
||||
#
|
||||
# @example Transforming summon data
|
||||
# data = {
|
||||
# "master" => { "name" => "Bahamut", "id" => "2040003000" },
|
||||
# "param" => { "evolution" => 5, "level" => 200 }
|
||||
# }
|
||||
# transformer = SummonTransformer.new(data, "2040003000")
|
||||
# result = transformer.transform
|
||||
# # => [{ name: "Bahamut", id: "2040003000", uncap: 5, transcend: 1, qs: true }]
|
||||
#
|
||||
# @note Expects data with "master" and "param" nested objects for each summon
|
||||
# @note Handles quick summon status if ID matches provided quick_summon_id
|
||||
#
|
||||
# @see BaseTransformer For base transformation functionality
|
||||
class SummonTransformer < BaseTransformer
|
||||
# @return [Array<Integer>] Level thresholds for determining transcendence level
|
||||
TRANSCENDENCE_LEVELS = [210, 220, 230, 240].freeze
|
||||
|
||||
# Creates a new summon transformer
|
||||
# @param data [Object] Raw summon data to transform
|
||||
# @param quick_summon_id [String, nil] ID of the current quick summon
|
||||
# @param options [Hash] Additional transformation options
|
||||
# @option options [String] :language ('en') Language for names
|
||||
# @option options [Boolean] :debug (false) Enable debug logging
|
||||
# @return [void]
|
||||
def initialize(data, quick_summon_id = nil, options = {})
|
||||
super(data, options)
|
||||
@quick_summon_id = quick_summon_id
|
||||
Rails.logger.info "[TRANSFORM] Initializing SummonTransformer with quick_summon_id: #{quick_summon_id}"
|
||||
end
|
||||
|
||||
# Transform raw summon data into standardized format
|
||||
# @return [Array<Hash>] Array of transformed summon data
|
||||
def transform
|
||||
Rails.logger.info "[TRANSFORM] Starting SummonTransformer#transform"
|
||||
|
||||
# Validate that input data is a Hash
|
||||
unless data.is_a?(Hash)
|
||||
Rails.logger.error "[TRANSFORM] Invalid summon data structure"
|
||||
Rails.logger.error "[TRANSFORM] Data class: #{data.class}"
|
||||
|
|
@ -21,24 +48,27 @@ module Granblue
|
|||
end
|
||||
|
||||
summons = []
|
||||
# Process each summon in the data
|
||||
data.each_value do |summon_data|
|
||||
Rails.logger.debug "[TRANSFORM] Processing summon: #{summon_data['master']['name'] if summon_data['master']}"
|
||||
|
||||
# Extract master and parameter data
|
||||
master, param = get_master_param(summon_data)
|
||||
unless master && param
|
||||
Rails.logger.debug "[TRANSFORM] Skipping summon - missing master or param data"
|
||||
next
|
||||
end
|
||||
|
||||
# Build base summon hash with required attributes
|
||||
summon = {
|
||||
name: master['name'],
|
||||
id: master['id'],
|
||||
uncap: param['evolution'].to_i
|
||||
name: master['name'], # Summon's display name
|
||||
id: master['id'], # Unique identifier
|
||||
uncap: param['evolution'].to_i # Current uncap level
|
||||
}
|
||||
|
||||
Rails.logger.debug "[TRANSFORM] Base summon data: #{summon}"
|
||||
|
||||
# Add transcendence if applicable
|
||||
# Add transcendence level for highly uncapped summons
|
||||
if summon[:uncap] > 5
|
||||
level = param['level'].to_i
|
||||
trans = calculate_transcendence_level(level)
|
||||
|
|
@ -46,7 +76,7 @@ module Granblue
|
|||
Rails.logger.debug "[TRANSFORM] Added transcendence level: #{trans}"
|
||||
end
|
||||
|
||||
# Mark quick summon if applicable
|
||||
# Mark quick summon status if this summon matches quick_summon_id
|
||||
if @quick_summon_id && param['id'].to_s == @quick_summon_id.to_s
|
||||
summon[:qs] = true
|
||||
Rails.logger.debug "[TRANSFORM] Marked as quick summon"
|
||||
|
|
@ -62,6 +92,9 @@ module Granblue
|
|||
|
||||
private
|
||||
|
||||
# Calculates transcendence level based on summon level
|
||||
# @param level [Integer, nil] Current summon level
|
||||
# @return [Integer] Calculated transcendence level (1-5)
|
||||
def calculate_transcendence_level(level)
|
||||
return 1 unless level
|
||||
level = 1 + TRANSCENDENCE_LEVELS.count { |cutoff| level > cutoff }
|
||||
|
|
|
|||
|
|
@ -1,20 +1,47 @@
|
|||
module Granblue
|
||||
module Transformers
|
||||
# Transforms raw game weapon data into standardized format for database import.
|
||||
# Handles weapon stats, uncap levels, transcendence, awakening, AX skills, and weapon keys.
|
||||
#
|
||||
# @example Transforming weapon data
|
||||
# data = {
|
||||
# "master" => { "name" => "Luminiera Sword Omega", "id" => "1040007100", "series_id" => 1 },
|
||||
# "param" => { "level" => 150, "arousal" => { "is_arousal_weapon" => true } }
|
||||
# }
|
||||
# transformer = WeaponTransformer.new(data)
|
||||
# result = transformer.transform
|
||||
# # => [{ name: "Luminiera Sword Omega", id: "1040007100", uncap: 4, ... }]
|
||||
#
|
||||
# @note Expects data with "master" and "param" nested objects for each weapon
|
||||
# @note Special handling for multi-element weapons from specific series
|
||||
#
|
||||
# @see BaseTransformer For base transformation functionality
|
||||
class WeaponTransformer < BaseTransformer
|
||||
# @return [Array<Integer>] Level thresholds for determining uncap level
|
||||
UNCAP_LEVELS = [40, 60, 80, 100, 150, 200].freeze
|
||||
|
||||
# @return [Array<Integer>] Level thresholds for determining transcendence level
|
||||
TRANSCENDENCE_LEVELS = [210, 220, 230, 240].freeze
|
||||
|
||||
# @return [Array<Integer>] Weapon series IDs that can have multiple elements
|
||||
MULTIELEMENT_SERIES = [13, 17, 19].freeze
|
||||
|
||||
# Transform raw weapon data into standardized format
|
||||
# @return [Array<Hash>] Array of transformed weapon data
|
||||
def transform
|
||||
# Log start of transformation process
|
||||
Rails.logger.info "[TRANSFORM] Starting WeaponTransformer#transform"
|
||||
|
||||
# Validate that the input data is a Hash
|
||||
unless data.is_a?(Hash)
|
||||
Rails.logger.error "[TRANSFORM] Invalid weapon data structure"
|
||||
return []
|
||||
end
|
||||
|
||||
weapons = []
|
||||
# Iterate through each weapon entry in the data
|
||||
data.each_value do |weapon_data|
|
||||
# Skip entries missing required master/param data
|
||||
next unless weapon_data['master'] && weapon_data['param']
|
||||
|
||||
master = weapon_data['master']
|
||||
|
|
@ -22,18 +49,23 @@ module Granblue
|
|||
|
||||
Rails.logger.debug "[TRANSFORM] Processing weapon: #{master['name']}"
|
||||
|
||||
# Transform base weapon attributes (ID, name, uncap level, etc)
|
||||
weapon = transform_base_attributes(master, param)
|
||||
Rails.logger.debug "[TRANSFORM] Base weapon attributes: #{weapon}"
|
||||
|
||||
# Add awakening data if present
|
||||
weapon.merge!(transform_awakening(param))
|
||||
Rails.logger.debug "[TRANSFORM] After awakening: #{weapon[:awakening] if weapon[:awakening]}"
|
||||
|
||||
# Add AX skills if present
|
||||
weapon.merge!(transform_ax_skills(param))
|
||||
Rails.logger.debug "[TRANSFORM] After AX skills: #{weapon[:ax] if weapon[:ax]}"
|
||||
|
||||
# Add weapon keys if present
|
||||
weapon.merge!(transform_weapon_keys(weapon_data))
|
||||
Rails.logger.debug "[TRANSFORM] After weapon keys: #{weapon[:keys] if weapon[:keys]}"
|
||||
|
||||
# Only add weapons with valid IDs
|
||||
weapons << weapon unless master['id'].nil?
|
||||
Rails.logger.info "[TRANSFORM] Successfully processed weapon #{weapon[:name]}"
|
||||
end
|
||||
|
|
@ -44,6 +76,10 @@ module Granblue
|
|||
|
||||
private
|
||||
|
||||
# Transforms the core weapon attributes from master and param data
|
||||
# @param master [Hash] Master data containing basic weapon information
|
||||
# @param param [Hash] Parameter data containing weapon's current state
|
||||
# @return [Hash] Base weapon attributes including ID, name, uncap level, etc
|
||||
def transform_base_attributes(master, param)
|
||||
Rails.logger.debug "[TRANSFORM] Processing base attributes for weapon"
|
||||
|
||||
|
|
@ -77,6 +113,9 @@ module Granblue
|
|||
weapon
|
||||
end
|
||||
|
||||
# Transforms weapon awakening data if present
|
||||
# @param param [Hash] Parameter data containing awakening information
|
||||
# @return [Hash] Awakening type and level if weapon is awakened
|
||||
def transform_awakening(param)
|
||||
return {} unless param['arousal']&.[]('is_arousal_weapon')
|
||||
|
||||
|
|
@ -89,6 +128,9 @@ module Granblue
|
|||
}
|
||||
end
|
||||
|
||||
# Transforms AX skill data if present
|
||||
# @param param [Hash] Parameter data containing AX skill information
|
||||
# @return [Hash] Array of AX skills with IDs and values
|
||||
def transform_ax_skills(param)
|
||||
augments = param['augment_skill_info']
|
||||
return {} unless augments&.first&.any?
|
||||
|
|
@ -107,6 +149,9 @@ module Granblue
|
|||
{ ax: ax }
|
||||
end
|
||||
|
||||
# Transforms weapon key data if present
|
||||
# @param weapon_data [Hash] Full weapon data containing key information
|
||||
# @return [Hash] Array of weapon key IDs
|
||||
def transform_weapon_keys(weapon_data)
|
||||
Rails.logger.debug "[TRANSFORM] Processing weapon keys"
|
||||
keys = []
|
||||
|
|
@ -122,11 +167,17 @@ module Granblue
|
|||
keys.any? ? { keys: keys } : {}
|
||||
end
|
||||
|
||||
# Calculates uncap level based on weapon level
|
||||
# @param level [Integer, nil] Current weapon level
|
||||
# @return [Integer] Calculated uncap level
|
||||
def calculate_uncap_level(level)
|
||||
return 0 unless level
|
||||
UNCAP_LEVELS.count { |cutoff| level.to_i > cutoff }
|
||||
end
|
||||
|
||||
# Calculates transcendence level based on weapon level
|
||||
# @param level [Integer, nil] Current weapon level
|
||||
# @return [Integer] Calculated transcendence level
|
||||
def calculate_transcendence_level(level)
|
||||
return 1 unless level
|
||||
1 + TRANSCENDENCE_LEVELS.count { |cutoff| level.to_i > cutoff }
|
||||
|
|
|
|||
31
sig/granblue/transformers/base_transformer.rbs
Normal file
31
sig/granblue/transformers/base_transformer.rbs
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
module Granblue
|
||||
module Transformers
|
||||
class TransformerError < StandardError
|
||||
attr_reader details: untyped
|
||||
|
||||
def initialize: (String message, ?untyped details) -> void
|
||||
end
|
||||
|
||||
class BaseTransformer
|
||||
ELEMENT_MAPPING: Hash[Integer, Integer?]
|
||||
|
||||
@data: untyped
|
||||
@options: Hash[Symbol, untyped]
|
||||
@language: String
|
||||
|
||||
attr_reader data: untyped
|
||||
attr_reader options: Hash[Symbol, untyped]
|
||||
attr_reader language: String
|
||||
|
||||
def initialize: (untyped data, ?Hash[Symbol, untyped] options) -> void
|
||||
|
||||
def transform: -> untyped
|
||||
|
||||
def validate_data: -> bool
|
||||
|
||||
def get_master_param: (Hash[String, untyped] obj) -> [Hash[String, untyped]?, Hash[String, untyped]?]
|
||||
|
||||
def log_debug: (String message) -> void
|
||||
end
|
||||
end
|
||||
end
|
||||
20
sig/granblue/transformers/summon_transformer.rbs
Normal file
20
sig/granblue/transformers/summon_transformer.rbs
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
module Granblue
|
||||
module Transformers
|
||||
class SummonTransformer < BaseTransformer
|
||||
# Level thresholds for transcendence calculations
|
||||
TRANSCENDENCE_LEVELS: Array[Integer]
|
||||
|
||||
# Quick summon ID for the current transformation
|
||||
@quick_summon_id: String?
|
||||
|
||||
def initialize: (untyped data, ?String? quick_summon_id, ?Hash[Symbol, untyped] options) -> void
|
||||
|
||||
# Implements abstract method from BaseTransformer
|
||||
def transform: -> Array[Hash[Symbol, untyped]]
|
||||
|
||||
private
|
||||
|
||||
def calculate_transcendence_level: (Integer? level) -> Integer
|
||||
end
|
||||
end
|
||||
end
|
||||
27
sig/granblue/transformers/weapon_transformer.rbs
Normal file
27
sig/granblue/transformers/weapon_transformer.rbs
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
module Granblue
|
||||
module Transformers
|
||||
class WeaponTransformer < BaseTransformer
|
||||
# Constants for level calculations
|
||||
UNCAP_LEVELS: Array[Integer]
|
||||
TRANSCENDENCE_LEVELS: Array[Integer]
|
||||
MULTIELEMENT_SERIES: Array[Integer]
|
||||
|
||||
# Implements abstract method from BaseTransformer
|
||||
def transform: -> Array[Hash[Symbol, untyped]]
|
||||
|
||||
private
|
||||
|
||||
def transform_base_attributes: (Hash[String, untyped] master, Hash[String, untyped] param) -> Hash[Symbol, untyped]
|
||||
|
||||
def transform_awakening: (Hash[String, untyped] param) -> Hash[Symbol, Hash[Symbol, untyped]]
|
||||
|
||||
def transform_ax_skills: (Hash[String, untyped] param) -> Hash[Symbol, Array[Hash[Symbol, untyped]]]
|
||||
|
||||
def transform_weapon_keys: (Hash[String, untyped] weapon_data) -> Hash[Symbol, Array[String]]
|
||||
|
||||
def calculate_uncap_level: (Integer? level) -> Integer
|
||||
|
||||
def calculate_transcendence_level: (Integer? level) -> Integer
|
||||
end
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue