module GameData class Species def self.sprite_bitmap_from_pokemon(pkmn, back = false, species = nil) species = pkmn.species if !species species = GameData::Species.get(species).id_number # Just to be sure it's a number return self.egg_sprite_bitmap(species, pkmn.form) if pkmn.egg? if back ret = self.back_sprite_bitmap(species, pkmn.shiny?, pkmn.bodyShiny?, pkmn.headShiny?) else ret = self.front_sprite_bitmap(species, pkmn.shiny?, pkmn.bodyShiny?, pkmn.headShiny?) end ret.scale_bitmap(pkmn.sprite_scale) #for pokemon with size differences return ret end def self.sprite_bitmap_from_pokemon_id(id, back = false, shiny = false, bodyShiny = false, headShiny = false) if back ret = self.back_sprite_bitmap(id, shiny, bodyShiny, headShiny) else ret = self.front_sprite_bitmap(id, shiny, bodyShiny, headShiny) end return ret end MAX_SHIFT_VALUE = 360 MINIMUM_OFFSET = 40 ADDITIONAL_OFFSET_WHEN_TOO_CLOSE = 40 MINIMUM_DEX_DIF = 20 def self.calculateShinyHueOffset(dex_number, isBodyShiny = false, isHeadShiny = false) if dex_number <= NB_POKEMON if SHINY_COLOR_OFFSETS[dex_number] return SHINY_COLOR_OFFSETS[dex_number] end body_number = dex_number head_number = dex_number else body_number = getBodyID(dex_number) head_number = getHeadID(dex_number, body_number) end if isBodyShiny && isHeadShiny && SHINY_COLOR_OFFSETS[body_number] && SHINY_COLOR_OFFSETS[head_number] offset = SHINY_COLOR_OFFSETS[body_number] + SHINY_COLOR_OFFSETS[head_number] elsif isHeadShiny && SHINY_COLOR_OFFSETS[head_number] offset = SHINY_COLOR_OFFSETS[head_number] elsif isBodyShiny && SHINY_COLOR_OFFSETS[body_number] offset = SHINY_COLOR_OFFSETS[body_number] else offset = calculateShinyHueOffsetDefaultMethod(body_number, head_number, dex_number, isBodyShiny, isHeadShiny) end return offset end def self.calculateShinyHueOffsetDefaultMethod(body_number, head_number, dex_number, isBodyShiny = false, isHeadShiny = false) dex_offset = dex_number #body_number = getBodyID(dex_number) #head_number=getHeadID(dex_number,body_number) dex_diff = (body_number - head_number).abs if isBodyShiny && isHeadShiny dex_offset = dex_number elsif isHeadShiny dex_offset = head_number elsif isBodyShiny dex_offset = dex_diff > MINIMUM_DEX_DIF ? body_number : body_number + ADDITIONAL_OFFSET_WHEN_TOO_CLOSE end offset = dex_offset + Settings::SHINY_HUE_OFFSET offset /= MAX_SHIFT_VALUE if offset > NB_POKEMON offset = MINIMUM_OFFSET if offset < MINIMUM_OFFSET offset = MINIMUM_OFFSET if (MAX_SHIFT_VALUE - offset).abs < MINIMUM_OFFSET offset += pbGet(VAR_SHINY_HUE_OFFSET) #for testing - always 0 during normal gameplay return offset end def self.getAutogenSprite(head_id, body_id) end # species can be either a number, a Species objet of a symbol def self.front_sprite_bitmap(species, isShiny = false, bodyShiny = false, headShiny = false) dex_number = getDexNumberForSpecies(species) if species.is_a?(Species) dex_number = species.id_number end spriteLoader = BattleSpriteLoader.new if isFusion(dex_number) body_id = getBodyID(dex_number) head_id = getHeadID(dex_number, body_id) sprite = spriteLoader.load_fusion_sprite(head_id,body_id) else if isTripleFusion?(dex_number) sprite = spriteLoader.load_triple_fusion_sprite(dex_number) else sprite = spriteLoader.load_base_sprite(dex_number) end end if isShiny sprite.shiftColors(self.calculateShinyHueOffset(dex_number, bodyShiny, headShiny)) end return sprite end # def self.front_sprite_bitmap(dex_number, isShiny = false, bodyShiny = false, headShiny = false) # # body_id = getBodyID(dex_number) # # head_id = getHeadID(dex_number, body_id) # # return getAutogenSprite(head_id,body_id) # # #la méthode est utilisé ailleurs avec d'autres arguments (gender, form, etc.) mais on les veut pas # if dex_number.is_a?(Symbol) # dex_number = GameData::Species.get(dex_number).id_number # end # filename = self.sprite_filename(dex_number) # sprite = (filename) ? AnimatedBitmap.new(filename) : nil # if isShiny # sprite.shiftColors(self.calculateShinyHueOffset(dex_number, bodyShiny, headShiny)) # end # return sprite # end def self.back_sprite_bitmap(dex_number, isShiny = false, bodyShiny = false, headShiny = false) # filename = self.sprite_filename(dex_number) # sprite = (filename) ? AnimatedBitmap.new(filename) : nil # if isShiny # sprite.shiftColors(self.calculateShinyHueOffset(dex_number, bodyShiny, headShiny)) # end # return sprite sprite = self.front_sprite_bitmap(dex_number,isShiny,bodyShiny,headShiny) return sprite#.mirror end def self.egg_sprite_bitmap(dex_number, form = nil) filename = self.egg_sprite_filename(dex_number, form) return (filename) ? AnimatedBitmap.new(filename) : nil end end end # def self.sprite_filename(dex_number) # #dex_number = GameData::NAT_DEX_MAPPING[dex_number] ? GameData::NAT_DEX_MAPPING[dex_number] : dex_number # if dex_number.is_a?(GameData::Species) # dex_number = dex_number.id_number # end # if dex_number.is_a?(Symbol) # dex_number = getDexNumberForSpecies(dex_number) # end # return nil if dex_number == nil # if dex_number <= Settings::NB_POKEMON # return get_unfused_sprite_path(dex_number) # else # if dex_number >= Settings::ZAPMOLCUNO_NB # specialPath = getSpecialSpriteName(dex_number) # return pbResolveBitmap(specialPath) # head_id = nil # else # body_id = getBodyID(dex_number) # head_id = getHeadID(dex_number, body_id) # return get_fusion_sprite_path(head_id, body_id) # # folder = head_id.to_s # # filename = sprintf("%s.%s.png", head_id, body_id) # end # end # # customPath = pbResolveBitmap(Settings::CUSTOM_BATTLERS_FOLDER_INDEXED + "/" + head_id.to_s + "/" +filename) # # customPath = download_custom_sprite(head_id,body_id) # # # # species = getSpecies(dex_number) # # use_custom = customPath && !species.always_use_generated # # if use_custom # # return customPath # # end # # #return Settings::BATTLERS_FOLDER + folder + "/" + filename # # return download_autogen_sprite(head_id,body_id) # end # def get_unfused_sprite_path(dex_number_id, localOnly = false) # dex_number = dex_number_id.to_s # folder = dex_number.to_s # substitution_id = _INTL("{1}", dex_number) # # if alt_sprites_substitutions_available && $PokemonGlobal.alt_sprite_substitutions.keys.include?(substitution_id) # substitutionPath = $PokemonGlobal.alt_sprite_substitutions[substitution_id] # return substitutionPath if pbResolveBitmap(substitutionPath) # end # random_alt = get_random_alt_letter_for_unfused(dex_number, true) #nil if no main # random_alt = "" if !random_alt || localOnly # # # filename = _INTL("{1}{2}.png", dex_number,random_alt) # # path = Settings::CUSTOM_BASE_SPRITES_FOLDER + filename # if pbResolveBitmap(path) # record_sprite_substitution(substitution_id,path) # return path # end # echoln "downloading main sprite #{filename}" # downloaded_path = download_unfused_main_sprite(dex_number, random_alt) if !localOnly # if pbResolveBitmap(downloaded_path) # record_sprite_substitution(substitution_id,downloaded_path) # return downloaded_path # end # return path # end def alt_sprites_substitutions_available return $PokemonGlobal && $PokemonGlobal.alt_sprite_substitutions end def print_stack_trace stack_trace = caller stack_trace.each_with_index do |call, index| echo("#{index + 1}: #{call}") end end # def record_sprite_substitution(substitution_id, sprite_name) # return if !$PokemonGlobal # return if !$PokemonGlobal.alt_sprite_substitutions # $PokemonGlobal.alt_sprite_substitutions[substitution_id] = sprite_name # end def add_to_autogen_cache(pokemon_id, sprite_name) return if !$PokemonGlobal return if !$PokemonGlobal.autogen_sprites_cache $PokemonGlobal.autogen_sprites_cache[pokemon_id]=sprite_name end class PokemonGlobalMetadata attr_accessor :autogen_sprites_cache end #To force a specific sprites before a battle # # ex: # $PokemonTemp.forced_alt_sprites={"20.25" => "20.25a"} # class PokemonTemp attr_accessor :forced_alt_sprites end #todo: # DO NOT USE ANYMORE # Replace by BattleSpriteLoader # def get_fusion_sprite_path(head_id, body_id, localOnly=false) # $PokemonGlobal.autogen_sprites_cache = {} if $PokemonGlobal && !$PokemonGlobal.autogen_sprites_cache # #Todo: ça va chier si on fusionne une forme d'un pokemon avec une autre forme, mais pas un problème pour tout de suite # form_suffix = "" # # #Swap path if alt is selected for this pokemon # dex_num = getSpeciesIdForFusion(head_id, body_id) # substitution_id = dex_num.to_s + form_suffix # # if alt_sprites_substitutions_available && $PokemonGlobal.alt_sprite_substitutions.keys.include?(substitution_id) # substitutionPath= $PokemonGlobal.alt_sprite_substitutions[substitution_id] # return substitutionPath if pbResolveBitmap(substitutionPath) # end # # # pokemon_name = _INTL("{1}.{2}",head_id, body_id) # # #get altSprite letter # random_alt = get_random_alt_letter_for_custom(head_id, body_id) #nil if no main # random_alt = "" if !random_alt # forcingSprite=false # if $PokemonTemp.forced_alt_sprites && $PokemonTemp.forced_alt_sprites.key?(pokemon_name) # random_alt = $PokemonTemp.forced_alt_sprites[pokemon_name] # forcingSprite=true # end # # # filename = _INTL("{1}{2}.png", pokemon_name, random_alt) # #Try local custom sprite # local_custom_path = Settings::CUSTOM_BATTLERS_FOLDER_INDEXED + head_id.to_s + "/" + filename # if pbResolveBitmap(local_custom_path) # record_sprite_substitution(substitution_id, local_custom_path) if !forcingSprite # return local_custom_path # end # #if the game has loaded an autogen earlier, no point in trying to redownload, so load that instead # return $PokemonGlobal.autogen_sprites_cache[substitution_id] if $PokemonGlobal && $PokemonGlobal.autogen_sprites_cache[substitution_id] # # #Try to download custom sprite if none found locally # downloaded_custom = download_custom_sprite(head_id, body_id, random_alt) if !localOnly # if downloaded_custom # record_sprite_substitution(substitution_id, downloaded_custom) if !forcingSprite # return downloaded_custom # end # # #Try local generated sprite # local_generated_path = Settings::BATTLERS_FOLDER + head_id.to_s + "/" + filename # if pbResolveBitmap(local_generated_path) # add_to_autogen_cache(substitution_id,local_generated_path) # return local_generated_path # end # # #Download generated sprite if nothing else found # autogen_path = download_autogen_sprite(head_id, body_id) if !localOnly # if pbResolveBitmap(autogen_path) # add_to_autogen_cache(substitution_id,autogen_path) # return autogen_path # end # # return Settings::DEFAULT_SPRITE_PATH # end def get_random_alt_letter_for_custom(head_id, body_id, onlyMain = true) spriteName = _INTL("{1}.{2}", head_id, body_id) if onlyMain alts_list = list_main_sprites_letters(spriteName) return nil if alts_list.empty? return alts_list.sample else alts_list = list_all_sprites_letters(spriteName) return nil if alts_list.empty? return alts_list.sample end end def get_random_alt_letter_for_unfused(dex_num, onlyMain = true) spriteName = _INTL("{1}", dex_num) if onlyMain letters_list= list_main_sprites_letters(spriteName) else letters_list= list_all_sprites_letters(spriteName) end letters_list << "" #add main sprite return letters_list.sample end def list_main_sprites_letters(spriteName) all_sprites = map_alt_sprite_letters_for_pokemon(spriteName) main_sprites = [] all_sprites.each do |key, value| main_sprites << key if value == "main" end #add temp sprites if no main sprites found if main_sprites.empty? all_sprites.each do |key, value| main_sprites << key if value == "temp" end end return main_sprites end def list_all_sprites_letters_head_body(head_id,body_id) spriteName = _INTL("{1}.{2}", head_id, body_id) all_sprites_map = map_alt_sprite_letters_for_pokemon(spriteName) letters = [] all_sprites_map.each do |key, value| letters << key end return letters end def list_all_sprites_letters(spriteName) all_sprites_map = map_alt_sprite_letters_for_pokemon(spriteName) letters = [] all_sprites_map.each do |key, value| letters << key end return letters end def list_alt_sprite_letters(spriteName) all_sprites = map_alt_sprite_letters_for_pokemon(spriteName) alt_sprites = [] all_sprites.each do |key, value| alt_sprites << key if value == "alt" end end #ex: "1" -> "main" # "1a" -> "alt" def map_alt_sprite_letters_for_pokemon(spriteName) alt_sprites = {} File.foreach(Settings::CREDITS_FILE_PATH) do |line| row = line.split(',') sprite_name = row[0] if sprite_name.start_with?(spriteName) if sprite_name.length > spriteName.length #alt letter letter = sprite_name[spriteName.length] if letter.match?(/[a-zA-Z]/) main_or_alt = row[2] ? row[2] : nil alt_sprites[letter] = main_or_alt end else #letterless main_or_alt = row[2] ? row[2].gsub("\n","") : nil alt_sprites[""] = main_or_alt end end end return alt_sprites end