Files
infinitefusion-e18/Data/Scripts/048_Fusion/FusedSpecies.rb
2024-12-22 11:27:23 -05:00

378 lines
12 KiB
Ruby

module GameData
class FusedSpecies < GameData::Species
attr_reader :growth_rate
attr_reader :body_pokemon
attr_reader :head_pokemon
def initialize(id)
if id.is_a?(Integer)
body_id = getBodyID(id)
head_id = getHeadID(id, body_id)
pokemon_id = getFusedPokemonIdFromDexNum(body_id, head_id)
return GameData::FusedSpecies.new(pokemon_id)
end
head_id = get_head_number_from_symbol(id)
body_id = get_body_number_from_symbol(id)
@body_pokemon = GameData::Species.get(body_id)
@head_pokemon = GameData::Species.get(head_id)
@id = id
@id_number = calculate_dex_number()
@species = @id
@form = 0
@real_name = calculate_name()
@real_form_name = nil
@type1 = calculate_type1()
@type2 = calculate_type2()
#Stats
@base_stats = calculate_base_stats()
@evs = calculate_evs()
adjust_stats_with_evs()
@base_exp = calculate_base_exp()
@growth_rate = calculate_growth_rate()
@gender_ratio = calculate_gender() #todo
@catch_rate = calculate_catch_rate()
@happiness = calculate_base_happiness()
#Moves
@moves = calculate_moveset()
@tutor_moves = calculate_tutor_moves() # hash[:tutor_moves] || []
@egg_moves = calculate_egg_moves() # hash[:egg_moves] || []
#Abilities
@abilities = calculate_abilities() # hash[:abilities] || []
@hidden_abilities = calculate_hidden_abilities() # hash[:hidden_abilities] || []
#wild held items
@wild_item_common = get_wild_item(@head_pokemon.wild_item_common, @body_pokemon.wild_item_common) # hash[:wild_item_common]
@wild_item_uncommon = get_wild_item(@head_pokemon.wild_item_uncommon, @body_pokemon.wild_item_uncommon) # hash[:wild_item_uncommon]
@wild_item_rare = get_wild_item(@head_pokemon.wild_item_rare, @body_pokemon.wild_item_rare) # hash[:wild_item_rare]
@evolutions = calculate_evolutions() # hash[:evolutions] || []
#breeding
@egg_groups = [:Undiscovered] #calculate_egg_groups() # hash[:egg_groups] || [:Undiscovered]
@hatch_steps = calculate_hatch_steps() # hash[:hatch_steps] || 1
@incense = nil #hash[:incense]
#pokedex
@pokedex_form = @form #ignored
@real_category = calculate_category()
@real_pokedex_entry = calculate_dex_entry()
@height = average_values(@head_pokemon.height, @body_pokemon.height)
@weight = average_values(@head_pokemon.weight, @body_pokemon.weight)
@color = @head_pokemon.color
@shape = @body_pokemon.shape
#sprite positioning
@back_sprite_x = @body_pokemon.back_sprite_x
@back_sprite_y = @body_pokemon.back_sprite_y
@front_sprite_x = @body_pokemon.front_sprite_x
@front_sprite_y = @body_pokemon.front_sprite_y
@front_sprite_altitude = @body_pokemon.front_sprite_altitude
@shadow_x = @body_pokemon.shadow_x
@shadow_size = @body_pokemon.shadow_size
# #unused attributes from Species class
#
# @shape = :Head
# @habitat = :None
# @generation = 0
# @mega_stone = nil
# @mega_move = nil
# @unmega_form = 0
# @mega_message = 0
end
def get_body_number_from_symbol(id)
return id.to_s.match(/\d+/)[0].to_i
end
def get_head_number_from_symbol(id)
return id.to_s.match(/(?<=H)\d+/)[0].to_i
end
def get_body_species
return @body_pokemon.id_number
end
def get_head_species
return @head_pokemon.id_number
end
def get_body_species_symbol
return @body_pokemon.id
end
def get_head_species_symbol
return @head_pokemon.id
end
def adjust_stats_with_evs
GameData::Stat.each_main do |s|
@base_stats[s.id] = 1 if !@base_stats[s.id] || @base_stats[s.id] <= 0
@evs[s.id] = 0 if !@evs[s.id] || @evs[s.id] < 0
end
end
#FUSION CALCULATIONS
def calculate_dex_number()
return (@body_pokemon.id_number * NB_POKEMON) + @head_pokemon.id_number
end
def calculate_type1()
return @head_pokemon.type2 if @head_pokemon.type1 == :NORMAL && @head_pokemon.type2 == :FLYING
return @head_pokemon.type1
end
def calculate_type2()
return @body_pokemon.type1 if @body_pokemon.type2 == @type1
return @body_pokemon.type2
end
def calculate_base_stats()
head_stats = @head_pokemon.base_stats
body_stats = @body_pokemon.base_stats
fused_stats = {}
#Head dominant stats
fused_stats[:HP] = calculate_fused_stats(head_stats[:HP], body_stats[:HP])
fused_stats[:SPECIAL_DEFENSE] = calculate_fused_stats(head_stats[:SPECIAL_DEFENSE], body_stats[:SPECIAL_DEFENSE])
fused_stats[:SPECIAL_ATTACK] = calculate_fused_stats(head_stats[:SPECIAL_ATTACK], body_stats[:SPECIAL_ATTACK])
#Body dominant stats
fused_stats[:ATTACK] = calculate_fused_stats(body_stats[:ATTACK], head_stats[:ATTACK])
fused_stats[:DEFENSE] = calculate_fused_stats(body_stats[:DEFENSE], head_stats[:DEFENSE])
fused_stats[:SPEED] = calculate_fused_stats(body_stats[:SPEED], head_stats[:SPEED])
return fused_stats
end
def calculate_base_exp()
head_exp = @head_pokemon.base_exp
body_exp = @body_pokemon.base_exp
return average_values(head_exp, body_exp)
end
def calculate_catch_rate
return get_lowest_value(@body_pokemon.catch_rate, @head_pokemon.catch_rate)
end
def calculate_base_happiness
return @head_pokemon.happiness
end
def calculate_moveset
return combine_arrays(@body_pokemon.moves, @head_pokemon.moves)
end
def calculate_egg_moves
return combine_arrays(@body_pokemon.egg_moves, @head_pokemon.egg_moves)
end
def calculate_tutor_moves
return combine_arrays(@body_pokemon.tutor_moves, @head_pokemon.tutor_moves)
end
def get_wild_item(body_item, head_item)
rand_num = rand(2)
if rand_num == 0
return body_item
else
return head_item
end
end
def calculate_abilities()
abilities_hash = []
ability1 = @body_pokemon.abilities[0]
ability2 = @head_pokemon.abilities[0]
abilities_hash << ability1
abilities_hash << ability2
return abilities_hash
end
# def calculate_abilities(pokemon1, pokemon2)
# abilities_hash = []
#
# ability1 = pokemon1.abilities[0]
# ability2 = pokemon2.abilities[1]
# if !ability2
# ability2 = pokemon2.abilities[0]
# end
# abilities_hash << ability1
# abilities_hash << ability2
# return abilities_hash
# end
def calculate_hidden_abilities()
abilities_hash = []
#First two spots are the other abilities of the two pokemon
ability1 = @body_pokemon.abilities[1]
ability2 = @head_pokemon.abilities[1]
ability1 = @body_pokemon.abilities[0] if !ability1
ability2 = @head_pokemon.abilities[0] if !ability2
abilities_hash << ability1
abilities_hash << ability2
#add the hidden ability for the two base pokemon
hiddenAbility1 = @body_pokemon.hidden_abilities[0]
hiddenAbility1 = ability1 if !hiddenAbility1
hiddenAbility2 = @head_pokemon.hidden_abilities[0]
hiddenAbility2 = ability2 if !hiddenAbility2
abilities_hash << hiddenAbility1
abilities_hash << hiddenAbility2
return abilities_hash
end
def calculate_name()
body_nat_dex = GameData::NAT_DEX_MAPPING[@body_pokemon.id_number] ? GameData::NAT_DEX_MAPPING[@body_pokemon.id_number] : @body_pokemon.id_number
head_nat_dex = GameData::NAT_DEX_MAPPING[@head_pokemon.id_number] ? GameData::NAT_DEX_MAPPING[@head_pokemon.id_number] : @head_pokemon.id_number
begin
prefix = GameData::SPLIT_NAMES[head_nat_dex][0]
suffix = GameData::SPLIT_NAMES[body_nat_dex][1]
if prefix[-1] == suffix[0]
prefix = prefix[0..-2]
end
return prefix + suffix
rescue
print("species with error: " + @species.to_s)
end
end
def calculate_evolutions()
body_evolutions = @body_pokemon.evolutions
head_evolutions = @head_pokemon.evolutions
fused_evolutions = []
#body
for evolution in body_evolutions
evolutionSpecies = evolution[0]
evolutionSpecies_dex = GameData::Species.get(evolutionSpecies).id_number
fused_species = _INTL("B{1}H{2}", evolutionSpecies_dex, @head_pokemon.id_number)
fused_evolutions << build_evolution_array(evolution, fused_species)
end
#head
for evolution in head_evolutions
evolutionSpecies = evolution[0]
evolutionSpecies_dex = GameData::Species.get(evolutionSpecies).id_number
fused_species = _INTL("B{1}H{2}", @body_pokemon.id_number, evolutionSpecies_dex)
fused_evolutions << build_evolution_array(evolution, fused_species)
end
return fused_evolutions
end
#Change the evolution species depending if head & body and keep the rest of the data the same
def build_evolution_array(evolution_data, new_species)
fused_evolution_array = []
fused_evolution_array << new_species.to_sym
#add the rest
for data in evolution_data
next if evolution_data.index(data) == 0
fused_evolution_array << data
end
return fused_evolution_array
end
def calculate_dex_entry
body_entry = @body_pokemon.real_pokedex_entry.gsub(@body_pokemon.real_name, @real_name)
head_entry = @head_pokemon.real_pokedex_entry.gsub(@head_pokemon.real_name, @real_name)
return split_and_combine_text(body_entry, head_entry, ".")
end
def calculate_egg_groups
body_egg_groups = @body_pokemon.egg_groups
head_egg_groups = @head_pokemon.egg_groups
return :Undiscovered if body_egg_groups.include?(:Undiscovered) || head_egg_groups.include?(:Undiscovered)
return combine_arrays(body_egg_groups, head_egg_groups)
end
def calculate_hatch_steps
return average_values(@head_pokemon.hatch_steps, @body_pokemon.hatch_steps)
end
def calculate_evs()
return average_map_values(@body_pokemon.evs, @head_pokemon.evs)
end
def calculate_category
return split_and_combine_text(@body_pokemon.category, @head_pokemon.category, " ")
end
def calculate_growth_rate
growth_rate_priority = [:Fast, :Medium, :Parabolic, :Fluctuating, :Erratic, :Slow] #todo rearrange order for balance?
body_growth_rate = @body_pokemon.growth_rate
head_growth_rate = @head_pokemon.growth_rate
base_growth_rates = [body_growth_rate, head_growth_rate]
for rate in growth_rate_priority
return rate if base_growth_rates.include?(rate)
end
return :Medium
end
#TODO
# ################## UNFINISHED ####################
def calculate_gender
return :Genderless
end
############################# UTIL METHODS ###############################
#Takes 2 strings, splits and combines them using the beginning of the first one and the end of the second one
# (for example for pokedex entries)
def split_and_combine_text(beginingText_full, endText_full, separator)
beginingText_split = beginingText_full.split(separator, 2)
endText_split = endText_full.split(separator, 2)
beginningText = beginingText_split[0]
endText = endText_split[1] && endText_split[1] != "" ? endText_split[1] : endText_split[0]
return beginningText + separator + endText
end
def calculate_fused_stats(dominantStat, otherStat)
return ((2 * dominantStat) / 3) + (otherStat / 3).floor
end
def average_values(value1, value2)
return ((value1 + value2) / 2).floor
end
def average_map_values(map1, map2)
averaged_map = map1.merge(map2) do |key, value1, value2|
((value1 + value2) / 2.0).floor
end
return averaged_map
end
def get_highest_value(value1, value2)
return value1 > value2 ? value1 : value2
end
def get_lowest_value(value1, value2)
return value1 < value2 ? value1 : value2
end
def combine_arrays(array1, array2)
return array1 + array2
end
end
end