Update 6.8

This commit is contained in:
chardub
2026-07-10 15:42:06 -04:00
parent 5b85e72cb2
commit 6a6f126a18
7871 changed files with 493194 additions and 224826 deletions
@@ -27,6 +27,25 @@ def get_top_artists(nb_names = 100)
.to_h
end
def getCCredits
hats_authors = extract_author_from_cc_json(Settings::HATS_DATA_PATH,5)
clothes_authors = extract_author_from_cc_json(Settings::CLOTHES_DATA_PATH,50)
hair_authors = extract_author_from_cc_json(Settings::HAIRSTYLE_DATA_PATH,20)
all_authors = (hats_authors + clothes_authors + hair_authors).tally
return all_authors
end
def extract_author_from_cc_json(file_path, sprites_per_submission=1)
json_data = File.read(file_path)
outfits_data = HTTPLite::JSON.parse(json_data)
authors = []
outfits_data.each do |data|
author = data['author']
authors.push(*([author] * sprites_per_submission)) if author && !author.empty?
end
return authors
end
def analyzeSpritesList(spritesList, mostPopularCallbackVariable = 1)
pokemon_map = Hash.new
for spritename in spritesList
@@ -222,7 +241,7 @@ def displayTeamFlag(frame)
$game_screen.pictures[flag_image_id].show(flag_path, 0, x_position, y_position, 50, 50)
$game_screen.pictures[frame_image_id].show("teamFlagFrame", 0, x_position, y_position, 50, 50)
name = species.real_name
pbMessage("\"Team #{name} Flag\"")
pbMessage(_INTL("\"Team {1} Flag\"",name))
display_team_flag_statistics(species)
@@ -410,7 +429,7 @@ def displayGalleryFrame(frame)
$game_screen.pictures[bg_image_id].show("pictureFrame", 0, 0, 0)
name = species.real_name
author = pbGet(259)
message = "\"#{name}\"\nBy #{author}"
message = _INTL("\"{1}\"\nBy {2}",name,author)
displaySpriteWindowWithMessage(pif_sprite, message, 90, -10, 201)
$game_screen.pictures[frame_image_id].erase
$game_screen.pictures[bg_image_id].erase
@@ -467,6 +486,23 @@ def format_names_for_game_credits()
return formatted
end
def format_character_customization_names_for_game_credits(max_length)
spriters_map = getCCredits.sort_by { |_, count| -count }.to_h
formatted = ""
i = 1
echoln spriters_map.keys.length
for spriter in spriters_map.keys
break if i > max_length
formatted << spriter
if i % 2 == 0
formatted << "\n"
else
formatted << "<s>"
end
i += 1
end
return formatted
end
def get_spritename_from_path(file_path, includeExtension = false)
filename_with_extension = File.basename(file_path)
@@ -496,4 +532,4 @@ end
# p spritename
# p getSpriteCredits(spritename)
# return getSpriteCredits(spritename)
# end
# end
@@ -58,7 +58,7 @@ module GameData
@evolutions = calculate_evolutions() # hash[:evolutions] || []
#breeding
@egg_groups = [:Undiscovered] #calculate_egg_groups() # hash[:egg_groups] || [:Undiscovered]
@egg_groups = calculate_egg_groups() # hash[:egg_groups] || [:Undiscovered]
@hatch_steps = calculate_hatch_steps() # hash[:hatch_steps] || 1
@incense = nil #hash[:incense]
@@ -268,8 +268,9 @@ module GameData
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]
split_names = get_split_names
prefix = split_names[head_nat_dex][0]
suffix = split_names[body_nat_dex][1]
if prefix[-1] == suffix[0]
prefix = prefix[0..-2]
end
@@ -282,6 +283,18 @@ module GameData
end
def get_split_names
case getCurrentLanguage
when :ENGLISH
return GameData::SPLIT_NAMES
when :FRENCH
return GameData::SPLIT_NAMES_FRENCH
when :CHINESE
return GameData::SPLIT_NAMES_CHINESE
end
return GameData::SPLIT_NAMES
end
def calculate_evolutions()
body_evolutions = @body_pokemon.evolutions
head_evolutions = @head_pokemon.evolutions
@@ -292,7 +305,7 @@ module GameData
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_species = "B#{evolutionSpecies_dex}H#{@head_pokemon.id_number}"
fused_evolutions << build_evolution_array(evolution, fused_species)
end
@@ -300,7 +313,7 @@ module GameData
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_species = "B#{@body_pokemon.id_number}H#{evolutionSpecies_dex}"
fused_evolutions << build_evolution_array(evolution, fused_species)
end
@@ -345,8 +358,6 @@ module GameData
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)
end
echoln body_entry
echoln head_entry
combined_entry = split_and_combine_text(body_entry, head_entry, ".")
combined_entry += "." unless combined_entry.end_with?(".")
return combined_entry
@@ -382,12 +393,15 @@ module GameData
return :Medium
end
#TODO
# ################## UNFINISHED ####################
def calculate_gender
return :Genderless
head_ratio = @head_pokemon.gender_ratio
body_ratio = @body_pokemon.gender_ratio
return :Genderless if head_ratio == :Genderless || body_ratio == :Genderless
return :Female50Percent
end
############################# UTIL METHODS ###############################
#Takes 2 strings, splits and combines them using the beginning of the first one and the end of the second one
@@ -273,7 +273,7 @@ module GameData
["Lo", "tad"],
["Lom", "bre"],
["Ludi", "colo"],
["Seed", "dot"],
["See", "dot"],
["Nuz", "leaf"],
["Shift", "try"],
["Tail", "low"],
@@ -293,7 +293,7 @@ module GameData
["Nin", "cada"],
["Nin", "jask"],
["Shed", "inja"],
["Whism", "mur"],
["Whis", "mur"],
["Loud", "dred"],
["Exp", "loud"],
["Maku", "hita"],
@@ -372,7 +372,7 @@ module GameData
["Reli", "canth"],
["Luv", "disc"],
["Ba", "agon"],
["Shel", "elgon"],
["Shel", "gon"],
["Sala", "mence"],
["Bel", "dum"],
["Met", "tang"],
@@ -423,10 +423,10 @@ module GameData
["Cher", "rubi"],
["Cherri", "rim"],
["Shell", "los"],
["Gastro", "trodon"],
["Gas", "trodon"],
["Ambi", "pom"],
["Drifl", "loon"],
["Drifb", "blim"],
["Drif", "loon"],
["Drif", "blim"],
["Bun", "eary"],
["Lop", "punny"],
["Mis", "magius"],
@@ -527,7 +527,7 @@ module GameData
["Roggen", "rola"],
["Bold", "dore"],
["Giga", "lith"],
["Woob", "obat"],
["Woo", "bat"],
["Swoo", "bat"],
["Drill", "bur"],
["Exca", "cadrill"],
@@ -602,11 +602,11 @@ module GameData
["Kli", "ink"],
["Kla", "ang"],
["Klink", "klang"],
["Tyna", "amo"],
["Eel", "lektrik"],
["Ty", "namo"],
["Eelek", "trik"],
["Eelek", "tross"],
["Elg", "gyem"],
["Behe", "eyem"],
["Behe", "yem"],
["Lit", "wick"],
["Lamp", "pent"],
["Chandel", "lure"],
@@ -621,7 +621,7 @@ module GameData
["Stun", "fisk"],
["Mie", "foo"],
["Mien", "shao"],
["Druddi", "digon"],
["Drud", "digon"],
["Gole", "olett"],
["Golu", "lurk"],
["Pawn", "iard"],
@@ -690,8 +690,8 @@ module GameData
["Mala", "lamar"],
["Bin", "nacle"],
["Barbar", "racle"],
["Skre", "relp"],
["Dragal", "galge"],
["Skr", "elp"],
["Drag", "alge"],
["Claunch", "auncher"],
["Claw", "witzer"],
["Heliop", "optile"],
@@ -1078,7 +1078,7 @@ module GameData
418 => 662,
419 => 636,
420 => 618,
#new pokes
# new pokes
421 => 302,
422 => 543,
423 => 544,
@@ -1160,70 +1160,77 @@ module GameData
499 => 774,
500 => 719,
501 => 370,
502 => 261 ,
503 => 262 ,
504 => 263 ,
505 => 264 ,
506 => 265 ,
507 => 266 ,
508 => 267 ,
509 => 268 ,
510 => 269 ,
511 => 273 ,
512 => 274 ,
513 => 275 ,
514 => 276 ,
515 => 277 ,
516 => 278 ,
517 => 279 ,
518 => 283 ,
519 => 284 ,
520 => 293 ,
521 => 294 ,
522 => 295 ,
523 => 296 ,
524 => 297 ,
525 => 300 ,
526 => 301 ,
527 => 307 ,
528 => 308 ,
529 => 309 ,
530 => 310 ,
531 => 311 ,
532 => 312 ,
533 => 313 ,
534 => 314 ,
535 => 316 ,
536 => 317 ,
537 => 322 ,
538 => 323 ,
539 => 325 ,
540 => 326 ,
541 => 327 ,
542 => 335 ,
543 => 336 ,
544 => 337 ,
545 => 338 ,
546 => 339 ,
547 => 340 ,
548 => 341 ,
549 => 342 ,
550 => 343 ,
551 => 344 ,
552 => 351 ,
553 => 351 ,
554 => 351 ,
555 => 351 ,
556 => 357 ,
557 => 433 ,
558 => 358 ,
559 => 363 ,
560 => 364 ,
561 => 365 ,
562 => 366 ,
563 => 367 ,
564 => 368 ,
565 => 369 ,
502 => 261,
503 => 262,
504 => 263,
505 => 264,
506 => 265,
507 => 266,
508 => 267,
509 => 268,
510 => 269,
511 => 273,
512 => 274,
513 => 275,
514 => 276,
515 => 277,
516 => 278,
517 => 279,
518 => 283,
519 => 284,
520 => 293,
521 => 294,
522 => 295,
523 => 296,
524 => 297,
525 => 300,
526 => 301,
527 => 307,
528 => 308,
529 => 309,
530 => 310,
531 => 311,
532 => 312,
533 => 313,
534 => 314,
535 => 316,
536 => 317,
537 => 322,
538 => 323,
539 => 325,
540 => 326,
541 => 327,
542 => 335,
543 => 336,
544 => 337,
545 => 338,
546 => 339,
547 => 340,
548 => 341,
549 => 342,
550 => 343,
551 => 344,
552 => 351,
553 => 351,
554 => 351,
555 => 351,
556 => 357,
557 => 433,
558 => 358,
559 => 363,
560 => 364,
561 => 365,
562 => 366,
563 => 367,
564 => 368,
565 => 369,
566 => 527,
567 => 528,
568 => 602,
569 => 603,
570 => 604,
571 => 690,
572 => 691,
}
end
@@ -1,259 +0,0 @@
class PokeBattle_Battler
attr_accessor :ability_id
attr_accessor :ability2_id
#Primary ability utility methods for battlers class
def ability
return GameData::Ability.try_get(@ability_id)
end
def ability=(value)
new_ability = GameData::Ability.try_get(value)
@ability_id = (new_ability) ? new_ability.id : nil
end
def abilityName
abil = self.ability
return (abil) ? abil.name : ""
end
#Secondary ability utility methods for battlers class
def ability2
return nil if !$game_switches[SWITCH_DOUBLE_ABILITIES]
return GameData::Ability.try_get(@ability2_id)
end
def ability2=(value)
return if !$game_switches[SWITCH_DOUBLE_ABILITIES]
new_ability = GameData::Ability.try_get(value)
@ability2_id = (new_ability) ? new_ability.id : nil
end
def ability2Name
abil = self.ability2
return (abil) ? abil.name : ""
end
#Ability logic overrides
def hasActiveAbility?(check_ability, ignore_fainted = false)
return hasActiveAbilityDouble?(check_ability, ignore_fainted) if $game_switches[SWITCH_DOUBLE_ABILITIES]
return false if !abilityActive?(ignore_fainted)
return check_ability.include?(@ability_id) if check_ability.is_a?(Array)
return self.ability == check_ability
end
def hasActiveAbilityDouble?(check_ability, ignore_fainted = false)
return false if !$game_switches[SWITCH_DOUBLE_ABILITIES]
return false if !abilityActive?(ignore_fainted)
if check_ability.is_a?(Array)
return check_ability.include?(@ability_id) || check_ability.include?(@ability2_id)
end
return self.ability == check_ability || self.ability2 == check_ability
end
def triggerAbilityEffectsOnHit(move, user, target)
# Target's ability
if target.abilityActive?(true)
oldHP = user.hp
BattleHandlers.triggerTargetAbilityOnHit(target.ability, user, target, move, @battle)
BattleHandlers.triggerTargetAbilityOnHit(target.ability2, user, target, move, @battle) if $game_switches[SWITCH_DOUBLE_ABILITIES] && target.ability2
user.pbItemHPHealCheck if user.hp < oldHP
end
# User's ability
if user.abilityActive?(true)
BattleHandlers.triggerUserAbilityOnHit(user.ability, user, target, move, @battle)
BattleHandlers.triggerUserAbilityOnHit(user.ability2, user, target, move, @battle) if $game_switches[SWITCH_DOUBLE_ABILITIES] && user.ability2
user.pbItemHPHealCheck
end
end
def pbCheckDamageAbsorption(user, target)
# Substitute will take the damage
if target.effects[PBEffects::Substitute] > 0 && !ignoresSubstitute?(user) &&
(!user || user.index != target.index)
target.damageState.substitute = true
return
end
# Disguise will take the damage
if !@battle.moldBreaker && target.isFusionOf(:MIMIKYU) &&
target.form == 0 && (target.ability == :DISGUISE || target.ability2 == :DISGUISE)
target.damageState.disguise = true
return
end
end
# Called when a Pokémon (self) enters battle, at the end of each move used,
# and at the end of each round.
def pbContinualAbilityChecks(onSwitchIn = false)
# Check for end of primordial weather
@battle.pbEndPrimordialWeather
# Trace
if $game_switches[SWITCH_DOUBLE_ABILITIES] && onSwitchIn
displayOpponentDoubleAbilities()
else
if hasActiveAbility?(:TRACE)
# NOTE: In Gen 5 only, Trace only triggers upon the Trace bearer switching
# in and not at any later times, even if a traceable ability turns
# up later. Essentials ignores this, and allows Trace to trigger
# whenever it can even in the old battle mechanics.
choices = []
@battle.eachOtherSideBattler(@index) do |b|
next if b.ungainableAbility? ||
[:POWEROFALCHEMY, :RECEIVER, :TRACE].include?(b.ability_id)
choices.push(b)
end
if choices.length > 0
choice = choices[@battle.pbRandom(choices.length)]
@battle.pbShowAbilitySplash(self)
self.ability = choice.ability
@battle.pbDisplay(_INTL("{1} traced {2}'s {3}!", pbThis, choice.pbThis(true), choice.abilityName))
@battle.pbHideAbilitySplash(self)
if !onSwitchIn && (unstoppableAbility? || abilityActive?)
BattleHandlers.triggerAbilityOnSwitchIn(self.ability, self, @battle)
end
end
end
end
end
def displayOpponentDoubleAbilities()
@battle.eachOtherSideBattler(@index) do |battler|
@battle.pbShowPrimaryAbilitySplash(battler,true)
@battle.pbShowSecondaryAbilitySplash(battler,true) if battler.isFusion?()
@battle.pbHideAbilitySplash(battler)
end
end
end
class Pokemon
attr_writer :ability_index
attr_writer :ability2_index
#Primary ability utility methods for pokemon class
def ability_index
@ability_index = (@personalID & 1) if !@ability_index
return @ability_index
end
def ability
return GameData::Ability.try_get(ability_id())
end
def ability=(value)
return if value && !GameData::Ability.exists?(value)
@ability = (value) ? GameData::Ability.get(value).id : value
end
#Secondary ability utility methods for pokemon class
def ability2_index
return nil if !$game_switches[SWITCH_DOUBLE_ABILITIES]
@ability2_index = (@personalID & 1) if !@ability2_index
return @ability2_index
end
def ability2
return nil if !$game_switches[SWITCH_DOUBLE_ABILITIES]
return GameData::Ability.try_get(ability2_id())
end
def ability2=(value)
return if !$game_switches[SWITCH_DOUBLE_ABILITIES]
return if value && !GameData::Ability.exists?(value)
@ability2 = (value) ? GameData::Ability.get(value).id : value
end
def ability_id
if !@ability
sp_data = species_data
abil_index = ability_index
#echoln abil_index
if abil_index >= 2 # Hidden ability
@ability = sp_data.hidden_abilities[abil_index - 2]
abil_index = (@personalID & 1) if !@ability
end
if !@ability # Natural ability or no hidden ability defined
if $game_switches[SWITCH_NO_LEVELS_MODE]
@ability = sp_data.abilities[0] || sp_data.abilities[0]
@ability2 = sp_data.abilities[1] || sp_data.abilities[0]
else
@ability = sp_data.abilities[abil_index] || sp_data.abilities[0]
end
end
end
return @ability
end
def ability2_id
return nil if !$game_switches[SWITCH_DOUBLE_ABILITIES]
if !@ability2
sp_data = species_data
abil_index = ability_index
if abil_index >= 2 # Hidden ability
@ability2 = sp_data.hidden_abilities[abil_index - 2]
abil_index = (@personalID & 1) if !@ability2
end
if !@ability2 # Natural ability or no hidden ability defined
@ability2 = sp_data.abilities[abil_index] || sp_data.abilities[0]
end
end
return @ability2
end
def adjustHPForWonderGuard(stats)
return self.ability == :WONDERGUARD ? 1 : stats[:HP] || ($game_switches[SWITCH_DOUBLE_ABILITIES] && self.ability2 == :WONDERGUARD)
end
end
class PokemonFusionScene
def pbChooseAbility(ability1Id,ability2Id)
ability1 = GameData::Ability.get(ability1Id)
ability2 = GameData::Ability.get(ability2Id)
availableNatures = []
availableNatures << @pokemon1.nature
availableNatures << @pokemon2.nature
setAbilityAndNatureAndNickname([ability1,ability2], availableNatures)
end
def setAbilityAndNatureAndNickname(abilitiesList, naturesList)
clearUIForMoves
if $game_switches[SWITCH_DOUBLE_ABILITIES]
scene = FusionSelectOptionsScene.new(nil, naturesList, @pokemon1, @pokemon2)
screen = PokemonOptionScreen.new(scene)
screen.pbStartScreen
@pokemon1.ability = abilitiesList[0]
@pokemon1.ability2 = abilitiesList[1]
else
scene = FusionSelectOptionsScene.new(abilitiesList, naturesList, @pokemon1, @pokemon2)
screen = PokemonOptionScreen.new(scene)
screen.pbStartScreen
selectedAbility = scene.selectedAbility
@pokemon1.body_original_ability_index = @pokemon1.ability_index
@pokemon1.head_original_ability_index = @pokemon2.ability_index
@pokemon1.ability = selectedAbility
@pokemon1.ability_index = getAbilityIndexFromID(selectedAbility.id,@pokemon1)
end
@pokemon1.nature = scene.selectedNature
if scene.hasNickname
@pokemon1.name = scene.nickname
end
end
end
@@ -1,389 +0,0 @@
#
# module BattleHandlers
# #
# # Speed calculation
# #
#
# def self.triggerSpeedCalcAbility(ability, battler, mult)
# ability1 = ability
# ability2 = battler.ability2
# calculateAbilitySpeedMultiplier(ability1, battler, mult)
# if $game_switches[SWITCH_DOUBLE_ABILITIES]
# calculateAbilitySpeedMultiplier(ability2, battler, mult)
# end
# return mult
# end
#
# def self.calculateAbilitySpeedMultiplier(ability, battler, mult)
# ability1 = ability
# ability2 = battler.ability2
# ret = SpeedCalcAbility.trigger(ability1, battler, mult) || SpeedCalcAbility.trigger(ability2, battler, mult)
# return (ret != nil) ? ret : mult
# end
#
# def self.triggerWeightCalcAbility(ability,battler,w)
# ability1 = ability
# ability2 = battler.ability2
# ret = WeightCalcAbility.trigger(ability1,battler,w) || WeightCalcAbility.trigger(ability2,battler,w)
# return (ret!=nil) ? ret : w
# end
#
#
#
#
# def self.triggerEOREffectAbility(ability,battler,battle)
# ability1 = ability
# ability2 = battler.ability2
#
# EOREffectAbility.trigger(ability1,battler,battle)
# EOREffectAbility.trigger(ability2,battler,battle)
# end
#
# def self.triggerEORGainItemAbility(ability,battler,battle)
# ability1 = ability
# ability2 = battler.ability2
#
# EORGainItemAbility.trigger(ability1,battler,battle)
# EORGainItemAbility.trigger(ability2,battler,battle)
# end
#
# def self.triggerCertainSwitchingUserAbility(ability,switcher,battle)
# ability1 = ability
# ability2 = switcher.ability2
#
# ret = CertainSwitchingUserAbility.trigger(ability1,switcher,battle) || CertainSwitchingUserAbility.trigger(ability2,switcher,battle)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerCertainSwitchingUserAbility(ability,switcher,battle)
# ability1 = ability
# ability2 = switcher.ability2
#
# ret = CertainSwitchingUserAbility.trigger(ability1,switcher,battle) || CertainSwitchingUserAbility.trigger(ability2,switcher,battle)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerTrappingTargetAbility(ability,switcher,bearer,battle)
# ability1 = ability
# ability2 = switcher.ability2
# ret = TrappingTargetAbility.trigger(ability1,switcher,bearer,battle) || TrappingTargetAbility.trigger(ability2,switcher,bearer,battle)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerAbilityOnSwitchIn(ability,battler,battle)
# ability1 = ability
# ability2 = battler.ability2
# AbilityOnSwitchIn.trigger(ability1,battler,battle)
# AbilityOnSwitchIn.trigger(ability2,battler,battle)
# end
#
# def self.triggerAbilityOnSwitchOut(ability,battler,endOfBattle)
# ability1 = ability
# ability2 = battler.ability2
# AbilityOnSwitchOut.trigger(ability1,battler,endOfBattle)
# AbilityOnSwitchOut.trigger(ability2,battler,endOfBattle)
# end
#
# def self.triggerAbilityChangeOnBattlerFainting(ability,battler,fainted,battle)
# ability1 = ability
# ability2 = battler.ability2
# AbilityChangeOnBattlerFainting.trigger(ability1,battler,fainted,battle)
# AbilityChangeOnBattlerFainting.trigger(ability2,battler,fainted,battle)
#
# end
#
# def self.triggerAbilityOnBattlerFainting(ability,battler,fainted,battle)
# ability1 = ability
# ability2 = battler.ability2
# AbilityOnBattlerFainting.trigger(ability1,battler,fainted,battle)
# AbilityOnBattlerFainting.trigger(ability2,battler,fainted,battle)
# end
#
#
# def self.triggerRunFromBattleAbility(ability,battler)
# ability1 = ability
# ability2 = battler.ability2
# ret = RunFromBattleAbility.trigger(ability1,battler) || RunFromBattleAbility.trigger(ability2,battler)
# return (ret!=nil) ? ret : false
# end
# ########
# # FROM HERE
# #
#
# def self.triggerAbilityOnHPDroppedBelowHalf(ability,user,battle)
# ability1 = ability
# ability2 = user.ability2
# ret = AbilityOnHPDroppedBelowHalf.trigger(ability1,user,battle) || AbilityOnHPDroppedBelowHalf.trigger(ability2,user,battle)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerStatusCheckAbilityNonIgnorable(ability,battler,status)
# ability1 = ability
# ability2 = battler.ability2
# ret = StatusCheckAbilityNonIgnorable.trigger(ability1,battler,status) || StatusCheckAbilityNonIgnorable.trigger(ability2,battler,status)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerStatusImmunityAbility(ability,battler,status)
# ability1 = ability
# ability2 = battler.ability2
# ret = StatusImmunityAbility.trigger(ability1,battler,status) || StatusImmunityAbility.trigger(ability2,battler,status)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerStatusImmunityAbilityNonIgnorable(ability,battler,status)
# ability1 = ability
# ability2 = battler.ability2
# ret = StatusImmunityAbilityNonIgnorable.trigger(ability1,battler,status) || StatusImmunityAbilityNonIgnorable.trigger(ability2,battler,status)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerStatusImmunityAllyAbility(ability,battler,status)
# ability1 = ability
# ability2 = battler.ability2
# ret = StatusImmunityAllyAbility.trigger(ability1,battler,status) || StatusImmunityAllyAbility.trigger(ability2,battler,status)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerAbilityOnStatusInflicted(ability,battler,user,status)
# ability1 = ability
# ability2 = battler.ability2
# AbilityOnStatusInflicted.trigger(ability1,battler,user,status)
# AbilityOnStatusInflicted.trigger(ability2,battler,user,status)
# end
#
# def self.triggerStatusCureAbility(ability,battler)
# ability1 = ability
# ability2 = battler.ability2
# ret = StatusCureAbility.trigger(ability1,battler) || StatusCureAbility.trigger(ability2,battler)
# return (ret!=nil) ? ret : false
# end
#
#
# def self.triggerStatLossImmunityAbility(ability,battler,stat,battle,showMessages)
# ability1 = ability
# ability2 = battler.ability2
# ret = StatLossImmunityAbility.trigger(ability1,battler,stat,battle,showMessages) || StatLossImmunityAbility.trigger(ability2,battler,stat,battle,showMessages)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerStatLossImmunityAbilityNonIgnorable(ability,battler,stat,battle,showMessages)
# ability1 = ability
# ability2 = battler.ability2
# ret = StatLossImmunityAbilityNonIgnorable.trigger(ability1,battler,stat,battle,showMessages) || StatLossImmunityAbilityNonIgnorable.trigger(ability2,battler,stat,battle,showMessages)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerStatLossImmunityAllyAbility(ability,bearer,battler,stat,battle,showMessages)
# ability1 = ability
# ability2 = battler.ability2
# ret = StatLossImmunityAllyAbility.trigger(ability1,bearer,battler,stat,battle,showMessages) || StatLossImmunityAllyAbility.trigger(ability2,bearer,battler,stat,battle,showMessages)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerAbilityOnStatGain(ability,battler,stat,user)
# ability1 = ability
# ability2 = battler.ability2
# AbilityOnStatGain.trigger(ability1,battler,stat,user)
# AbilityOnStatGain.trigger(ability2,battler,stat,user)
# end
#
# def self.triggerAbilityOnStatLoss(ability,battler,stat,user)
# ability1 = ability
# ability2 = battler.ability2
# AbilityOnStatLoss.trigger(ability1,battler,stat,user)
# AbilityOnStatLoss.trigger(ability2,battler,stat,user)
# end
#
# #=============================================================================
#
#
# def self.triggerPriorityChangeAbility(ability,battler,move,pri)
# ability1 = ability
# ability2 = battler.ability2
# ret = PriorityChangeAbility.trigger(ability1,battler,move,pri) || PriorityChangeAbility.trigger(ability2,battler,move,pri)
# return (ret!=nil) ? ret : pri
# end
#
# def self.triggerPriorityBracketChangeAbility(ability,battler,subPri,battle)
# ability1 = ability
# ability2 = battler.ability2
# ret = PriorityBracketChangeAbility.trigger(ability1,battler,subPri,battle) || PriorityBracketChangeAbility.trigger(ability2,battler,subPri,battle)
# return (ret!=nil) ? ret : subPri
# end
#
# def self.triggerPriorityBracketUseAbility(ability,battler,battle)
# ability1 = ability
# ability2 = battler.ability2
# PriorityBracketUseAbility.trigger(ability1,battler,battle)
# PriorityBracketUseAbility.trigger(ability2,battler,battle)
# end
#
# #=============================================================================
#
# def self.triggerAbilityOnFlinch(ability,battler,battle)
# ability1 = ability
# ability2 = battler.ability2
# AbilityOnFlinch.trigger(ability1,battler,battle)
# AbilityOnFlinch.trigger(ability2,battler,battle)
# end
#
# def self.triggerMoveBlockingAbility(ability,bearer,user,targets,move,battle)
# ability1 = ability
# ability2 = bearer.ability2
# ret = MoveBlockingAbility.trigger(ability1,bearer,user,targets,move,battle) || MoveBlockingAbility.trigger(ability2,bearer,user,targets,move,battle)
# return (ret!=nil) ? ret : false
# end
#
# def self.triggerMoveImmunityTargetAbility(ability,user,target,move,type,battle)
# ability1 = ability
# ability2 = user.ability2
# ret = MoveImmunityTargetAbility.trigger(ability1,user,target,move,type,battle) || MoveImmunityTargetAbility.trigger(ability2,user,target,move,type,battle)
# return (ret!=nil) ? ret : false
# end
#
# #=============================================================================
#
# def self.triggerMoveBaseTypeModifierAbility(ability,user,move,type)
# ability1 = ability
# ability2 = user.ability2
# ret = MoveBaseTypeModifierAbility.trigger(ability1,user,move,type) || MoveBaseTypeModifierAbility.trigger(ability2,user,move,type)
# return (ret!=nil) ? ret : type
# end
#
# #=============================================================================
#
# def self.triggerAccuracyCalcUserAbility(ability,mods,user,target,move,type)
# ability1 = ability
# ability2 = user.ability2
# AccuracyCalcUserAbility.trigger(ability1,mods,user,target,move,type)
# AccuracyCalcUserAbility.trigger(ability2,mods,user,target,move,type)
# end
#
# def self.triggerAccuracyCalcUserAllyAbility(ability,mods,user,target,move,type)
# ability1 = ability
# ability2 = user.ability2
# AccuracyCalcUserAllyAbility.trigger(ability1,mods,user,target,move,type)
# AccuracyCalcUserAllyAbility.trigger(ability2,mods,user,target,move,type)
# end
#
# def self.triggerAccuracyCalcTargetAbility(ability,mods,user,target,move,type)
# ability1 = ability
# ability2 = user.ability2
# AccuracyCalcTargetAbility.trigger(ability1,mods,user,target,move,type)
# AccuracyCalcTargetAbility.trigger(ability2,mods,user,target,move,type)
# end
# #=============================================================================
#
# def self.triggerDamageCalcUserAbility(ability,user,target,move,mults,baseDmg,type)
# ability1 = ability
# ability2 = user.ability2
# DamageCalcUserAbility.trigger(ability1,user,target,move,mults,baseDmg,type)
# DamageCalcUserAbility.trigger(ability2,user,target,move,mults,baseDmg,type)
# end
#
# def self.triggerDamageCalcUserAllyAbility(ability,user,target,move,mults,baseDmg,type)
# ability1 = ability
# ability2 = target.ability2
# DamageCalcUserAllyAbility.trigger(ability1,user,target,move,mults,baseDmg,type)
# DamageCalcUserAllyAbility.trigger(ability2,user,target,move,mults,baseDmg,type)
# end
#
# def self.triggerDamageCalcTargetAbility(ability,user,target,move,mults,baseDmg,type)
# ability1 = ability
# ability2 = target.ability2
# DamageCalcTargetAbility.trigger(ability1,user,target,move,mults,baseDmg,type)
# DamageCalcTargetAbility.trigger(ability2,user,target,move,mults,baseDmg,type)
# end
#
# def self.triggerDamageCalcTargetAbilityNonIgnorable(ability,user,target,move,mults,baseDmg,type)
# ability1 = ability
# ability2 = target.ability2
# DamageCalcTargetAbilityNonIgnorable.trigger(ability1,user,target,move,mults,baseDmg,type)
# DamageCalcTargetAbilityNonIgnorable.trigger(ability2,user,target,move,mults,baseDmg,type)
# end
#
# def self.triggerDamageCalcTargetAllyAbility(ability,user,target,move,mults,baseDmg,type)
# ability1 = ability
# ability2 = target.ability2
# DamageCalcTargetAllyAbility.trigger(ability1,user,target,move,mults,baseDmg,type)
# DamageCalcTargetAllyAbility.trigger(ability2,user,target,move,mults,baseDmg,type)
# end
#
# #=============================================================================
#
# def self.triggerCriticalCalcUserAbility(ability,user,target,c)
# ability1 = ability
# ability2 = user.ability2
# ret = CriticalCalcUserAbility.trigger(ability1,user,target,c) || CriticalCalcUserAbility.trigger(ability2,user,target,c)
# return (ret!=nil) ? ret : c
# end
#
# def self.triggerCriticalCalcTargetAbility(ability,user,target,c)
# ability1 = ability
# ability2 = target.ability2
# ret = CriticalCalcTargetAbility.trigger(ability1,user,target,c) || CriticalCalcTargetAbility.trigger(ability2,user,target,c)
# return (ret!=nil) ? ret : c
# end
# #=============================================================================
#
# def self.triggerTargetAbilityOnHit(ability,user,target,move,battle)
# ability1 = ability
# ability2 = target.ability2
# TargetAbilityOnHit.trigger(ability1,user,target,move,battle)
# TargetAbilityOnHit.trigger(ability2,user,target,move,battle)
# end
#
# def self.triggerUserAbilityOnHit(ability,user,target,move,battle)
# ability1 = ability
# ability2 = user.ability2
# UserAbilityOnHit.trigger(ability1,user,target,move,battle)
# UserAbilityOnHit.trigger(ability2,user,target,move,battle)
# end
# #=============================================================================
#
# def self.triggerUserAbilityEndOfMove(ability,user,targets,move,battle)
# ability1 = ability
# ability2 = user.ability2
# UserAbilityEndOfMove.trigger(ability1,user,targets,move,battle)
# UserAbilityEndOfMove.trigger(ability2,user,targets,move,battle)
# end
#
# def self.triggerTargetAbilityAfterMoveUse(ability,target,user,move,switched,battle)
# ability1 = ability
# ability2 = target.ability2
# TargetAbilityAfterMoveUse.trigger(ability1,target,user,move,switched,battle)
# TargetAbilityAfterMoveUse.trigger(ability2,target,user,move,switched,battle)
# end
#
# #=============================================================================
#
# def self.triggerEORWeatherAbility(ability,weather,battler,battle)
# ability1 = ability
# ability2 = battler.ability2
# EORWeatherAbility.trigger(ability1,weather,battler,battle)
# EORWeatherAbility.trigger(ability2,weather,battler,battle)
# end
#
# def self.triggerEORHealingAbility(ability,battler,battle)
# ability1 = ability
# ability2 = battler.ability2
# EORHealingAbility.trigger(ability1,battler,battle)
# EORHealingAbility.trigger(ability2,battler,battle)
# end
#
# def self.triggerEOREffectAbility(ability,battler,battle)
# ability1 = ability
# ability2 = battler.ability2
# EOREffectAbility.trigger(ability1,battler,battle)
# EOREffectAbility.trigger(ability2,battler,battle)
# end
#
# def self.triggerEORGainItemAbility(ability,battler,battle)
# ability1 = ability
# ability2 = battler.ability2
# EORGainItemAbility.trigger(ability1,battler,battle)
# EORGainItemAbility.trigger(ability2,battler,battle)
# end
#
# end
@@ -1,130 +0,0 @@
#
# class AbilitySplashBar < SpriteWrapper
# def refresh
# self.bitmap.clear
# return if !@battler
# textPos = []
# textX = (@side==0) ? 10 : self.bitmap.width-8
# # Draw Pokémon's name
# textPos.push(["{1}'s",@battler.name,textX,-4,@side==1,
# TEXT_BASE_COLOR,TEXT_SHADOW_COLOR,true])
# # Draw Pokémon's ability
# textPos.push([@battler.abilityName,textX,26,@side==1,
# TEXT_BASE_COLOR,TEXT_SHADOW_COLOR,true])
# pbDrawTextPositions(self.bitmap,textPos)
#
# #2nd ability
# if $game_switches[SWITCH_DOUBLE_ABILITIES]
# textPos.push([@battler.ability2Name,textX,26,@side==1,
# TEXT_BASE_COLOR,TEXT_SHADOW_COLOR,true])
# pbDrawTextPositions(self.bitmap,textPos)
# end
# end
# end
class AbilitySplashDisappearAnimation < PokeBattle_Animation
def initialize(sprites,viewport,side)
@side = side
super(sprites,viewport)
end
def createProcesses
return if !@sprites["abilityBar_#{@side}"]
bar = addSprite(@sprites["abilityBar_#{@side}"])
bar2 = addSprite(@sprites["ability2Bar_#{@side}"]) if @sprites["ability2Bar_#{@side}"]
dir = (@side==0) ? -1 : 1
bar.moveDelta(0,8,dir*Graphics.width/2,0)
bar2.moveDelta(0,8,dir*Graphics.width/2,0) if bar2
bar.setVisible(8,false)
bar2.setVisible(8,false) if bar2
end
end
class PokeBattle_Scene
def pbShowAbilitySplash(battler,secondAbility=false, abilityName=nil)
return if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH
side = battler.index%2
if secondAbility
pbHideAbilitySplash(battler) if @sprites["ability2Bar_#{side}"].visible
else
pbHideAbilitySplash(battler) if @sprites["abilityBar_#{side}"].visible
end
if abilityName
@sprites["abilityBar_#{side}"].ability_name = abilityName if !secondAbility
@sprites["ability2Bar_#{side}"].ability_name = abilityName if secondAbility
end
@sprites["abilityBar_#{side}"].battler = battler
@sprites["ability2Bar_#{side}"].battler = battler if @sprites["ability2Bar_#{side}"]
abilitySplashAnim = AbilitySplashAppearAnimation.new(@sprites,@viewport,side,secondAbility)
loop do
abilitySplashAnim.update
pbUpdate
break if abilitySplashAnim.animDone?
end
abilitySplashAnim.dispose
end
end
class PokeBattle_Battle
def pbShowSecondaryAbilitySplash(battler,delay=false,logTrigger=true)
return if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH
@scene.pbShowAbilitySplash(battler,true)
if delay
Graphics.frame_rate.times { @scene.pbUpdate } # 1 second
end
end
def pbShowPrimaryAbilitySplash(battler,delay=false,logTrigger=true)
return if !PokeBattle_SceneConstants::USE_ABILITY_SPLASH
@scene.pbShowAbilitySplash(battler,false)
if delay
Graphics.frame_rate.times { @scene.pbUpdate } # 1 second
end
end
end
class FusionSelectOptionsScene < PokemonOption_Scene
def pbGetOptions(inloadscreen = false)
options = []
if shouldSelectNickname
options << EnumOption.new(_INTL("Nickname"), [_INTL(@pokemon1.name), _INTL(@pokemon2.name)],
proc { 0 },
proc { |value|
if value ==0
@nickname = @pokemon1.name
else
@nickname = @pokemon2.name
end
}, _INTL("Select the Pokémon's nickname"))
end
if @abilityList != nil
options << EnumOption.new(_INTL("Ability"), [_INTL(getAbilityName(@abilityList[0])), _INTL(getAbilityName(@abilityList[1]))],
proc { 0 },
proc { |value|
@selectedAbility=@abilityList[value]
}, [getAbilityDescription(@abilityList[0]), getAbilityDescription(@abilityList[1])]
)
end
options << EnumOption.new(_INTL("Nature"), [_INTL(getNatureName(@natureList[0])), _INTL(getNatureName(@natureList[1]))],
proc { 0 },
proc { |value|
@selectedNature=@natureList[value]
}, [getNatureDescription(@natureList[0]), getNatureDescription(@natureList[1])]
)
return options
end
end
@@ -0,0 +1,184 @@
def pbUnfuse(pokemon, scene, partyPosition=nil, pcPosition = nil)
if pokemon.original_body && pokemon.original_head
if pcPosition
result = unfusePokemonFromPC(pokemon, scene, pcPosition)
else
result = unfusePokemonFromParty(pokemon, scene, partyPosition)
end
else
result =unfusePokemonLegacy(pokemon, scene, false, pcPosition) #still used for wild Fusions
end
$PokemonTemp.unfuse_count_today = 0 unless $PokemonTemp.unfuse_count_today
$PokemonTemp.unfuse_count_today += 1
checkUnfuseChallenges(pokemon)
return result
end
def unfusePokemonFromPC(fused_pokemon, scene, pcPosition)
return unless pokemonCanBeUnfused(fused_pokemon, scene)
if pbConfirmMessage(_INTL("Should {1} be unfused?", fused_pokemon.name))
head_pokemon,body_pokemon = unfuseCore(fused_pokemon)
obtainUnfusedPokemonPC(head_pokemon, body_pokemon, pcPosition)
pbSEPlay("Minimize")
pbMessage(_INTL("Unfusing...\\....\\....\\....\\wtnp[5]"))
pbSEPlay("Voltorb Flip Point")
pbMessage(_INTL("Your Pokémon were successfully unfused!"))
return true
else
return false
end
end
def unfusePokemonFromParty(fused_pokemon, scene, partyPosition)
return unless pokemonCanBeUnfused(fused_pokemon, scene)
if pbConfirmMessage(_INTL("Should {1} be unfused?", fused_pokemon.name))
head_pokemon,body_pokemon = unfuseCore(fused_pokemon)
obtainUnfusedPokemonParty(head_pokemon, body_pokemon, partyPosition)
pbSEPlay("Minimize")
pbMessage(_INTL("Unfusing...\\....\\....\\....\\wtnp[5]"))
pbSEPlay("Voltorb Flip Point")
scene.pbHardRefresh
pbMessage(_INTL("Your Pokémon were successfully unfused!"))
return true
else
return false
end
end
def unfuseCore(fused_pokemon)
head_pokemon = fused_pokemon.original_head
body_pokemon = fused_pokemon.original_body
fused_head_species = fused_pokemon.species_data.head_pokemon.species
fused_body_species = fused_pokemon.species_data.body_pokemon.species
#If the Pokemon evolved while fused
if fused_head_species != head_pokemon.species
head_pokemon.species = fused_head_species
head_pokemon.pif_sprite = nil
end
if fused_body_species != body_pokemon.species
body_pokemon.species = fused_body_species
body_pokemon.pif_sprite = nil
end
#Items
$PokemonBag.pbStoreItem(fused_pokemon.item, 1) if fused_pokemon.item
fused_pokemon.exp_gained_since_fused =0 unless fused_pokemon.exp_gained_since_fused
# Exp
head_pokemon.exp_gained_with_player = 0 unless head_pokemon.exp_gained_with_player
head_pokemon.exp_gained_with_player += fused_pokemon.exp_gained_since_fused
head_pokemon.exp += fused_pokemon.exp_gained_since_fused
body_pokemon.exp_gained_with_player = 0 unless body_pokemon.exp_gained_with_player
body_pokemon.exp_gained_with_player += fused_pokemon.exp_gained_since_fused
body_pokemon.exp +=fused_pokemon.exp_gained_since_fused
head_pokemon.calc_stats
body_pokemon.calc_stats
# Moves
fused_pokemon_learned_moved = fused_pokemon.learned_moves
fused_pokemon_learned_moved = [] unless fused_pokemon_learned_moved
fused_pokemon_learned_moved.each do |move|
fused_pokemon_learned_moved << move unless fused_pokemon_learned_moved.include?(move)
end
fused_pokemon_learned_moved.each do |move|
head_pokemon.add_learned_move(move)
body_pokemon.add_learned_move(move)
end
head_pokemon.evolve_from_party = false
body_pokemon.evolve_from_party = false
# Pokedex
$Trainer.pokedex.set_seen(head_pokemon.species)
$Trainer.pokedex.set_owned(head_pokemon.species)
$Trainer.pokedex.set_seen(body_pokemon.species)
$Trainer.pokedex.set_owned(body_pokemon.species)
return [head_pokemon,body_pokemon]
end
def obtainUnfusedPokemonPC(head_pokemon, body_pokemon, pcPosition)
box = pcPosition[0]
index = pcPosition[1]
# todo: store at next available position from current position
$PokemonStorage.pbDelete(box,index)
if box == -1 #Player party
pbAddPokemonSilent(head_pokemon)
pbAddPokemonSilent(body_pokemon)
else
$PokemonStorage.pbStoreCaught(head_pokemon)
$PokemonStorage.pbStoreCaught(body_pokemon)
end
end
def obtainUnfusedPokemonParty(head_pokemon, body_pokemon, partyPosition)
if $Trainer.party.length >= 6
message = _INTL("Your party is full! Keep which Pokémon in party?")
message = _INTL("Your party is full! Keep which Pokémon in party? The other will be released.") if isOnPinkanIsland()
pbMessage(message)
selectPokemonMessage = _INTL("Select a Pokémon to keep in your party.")
selectPokemonMessage = _INTL("Select a Pokémon to keep in your party. The other will be released") if isOnPinkanIsland()
choice = Kernel.pbMessage(selectPokemonMessage, ["#{head_pokemon.name}", "#{body_pokemon.name}", _INTL("Cancel")], 2)
#Removes the fusion, then store in an order that depends on which one is sent to PC
if choice == 0 # Head
if isOnPinkanIsland()
$Trainer.party.delete_at(partyPosition)
pbAddPokemon(head_pokemon)
else
$Trainer.party[partyPosition] = head_pokemon
$PokemonStorage.pbStoreCaught(body_pokemon)
end
elsif choice == 1 #body
if isOnPinkanIsland()
$Trainer.party.delete_at(partyPosition)
pbAddPokemon(body_pokemon)
else
$Trainer.party[partyPosition] = body_pokemon
$PokemonStorage.pbStoreCaught(head_pokemon)
end
else
return false
end
else
storeUnfusedPokemonInPlace(partyPosition,head_pokemon,body_pokemon)
end
return true
end
def storeUnfusedPokemonInPlace(fusedPokemonPartyPosition, pokemonKeptInParty, pokemonSentToPC)
$Trainer.party[fusedPokemonPartyPosition] = pokemonKeptInParty
pbAddPokemonSilent(pokemonSentToPC)
end
def storeUnfusedPokemon(fusedPokemonPartyPosition, pokemonKeptInParty,pokemonSentToPC)
$Trainer.party.delete_at(fusedPokemonPartyPosition)
pbAddPokemonSilent(pokemonKeptInParty)
pbAddPokemonSilent(pokemonSentToPC)
end
def pokemonCanBeUnfused(pokemon, scene)
if pokemon.species_data.id_number > (NB_POKEMON * NB_POKEMON) + NB_POKEMON # triple fusion
scene.pbDisplay(_INTL("{1} cannot be unfused.", pokemon.name))
return false
end
if pokemon.egg?
scene.pbDisplay(_INTL("It won't have any effect."))
return false
end
if pokemon.owner.name == "RENTAL"
scene.pbDisplay(_INTL("You cannot unfuse a rental pokémon!"))
return false
end
if (pokemon.foreign?($Trainer)) # && !canunfuse
scene.pbDisplay(_INTL("You can't unfuse a Pokémon obtained in a trade!"))
return false
end
return true
end
@@ -1,240 +0,0 @@
class FusionMovesOptionsScene < PokemonOption_Scene
attr_accessor :move1
attr_accessor :move2
attr_accessor :move3
attr_accessor :move4
def initialize(poke1, poke2)
@poke1 = poke1
@poke2 = poke2
@move1 = @poke1.moves[0]
@move2 = @poke1.moves[1]
@move3 = @poke1.moves[2]
@move4 = @poke1.moves[3]
@index1=0
@index2=0
@index3=0
@index4=0
@selBaseColor = Color.new(48,96,216)
@selShadowColor = Color.new(32,32,32)
end
def initUIElements
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(
_INTL(""), 0, 0, Graphics.width, 64, @viewport)
@sprites["textbox"] = pbCreateMessageWindow
@sprites["textbox"].letterbyletter = false
pbSetSystemFont(@sprites["textbox"].contents)
end
def pbStartScene(inloadscreen = false)
super
@typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
@sprites["overlay"] = BitmapSprite.new(Graphics.width, Graphics.height, @viewport)
@sprites["overlay"].z = 9999
pbSetSystemFont(@sprites["overlay"].bitmap)
@sprites["option"].nameBaseColor = MessageConfig::BLUE_TEXT_MAIN_COLOR
@sprites["option"].nameShadowColor = MessageConfig::BLUE_TEXT_SHADOW_COLOR
@changedColor = true
for i in 0...@PokemonOptions.length
@sprites["option"][i] = (@PokemonOptions[i].get || 0)
end
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(
_INTL("Select moves"), 0, 0, Graphics.width, 64, @viewport)
@sprites["title"].setSkin("Graphics/Windowskins/invisible")
@sprites["option"].setSkin("Graphics/Windowskins/invisible")
@sprites["textbox"].setSkin("Graphics/Windowskins/invisible")
# @sprites["textbox"].text = "Select moves"
updateDescription(0)
pbFadeInAndShow(@sprites) { pbUpdate }
end
def draw_empty_move_info
# code here
end
def draw_move_info(pokemonMove)
move = GameData::Move.get(pokemonMove.id)
move_base_color = Color.new(50, 40, 230)
move_base_shadow = Color.new(14, 14, 114)
label_base_color = Color.new(248, 248, 248)
label_shadow_color = Color.new(104, 104, 104)
value_base_color = Color.new(248, 248, 248)
value_shadow_color = Color.new(104, 104, 104)
@sprites["title"].text = _INTL("{1}", move.real_name)
damage = move.base_damage == 0 ? "-" : move.base_damage.to_s
accuracy = move.accuracy == 0 ? "100" : move.accuracy.to_s
pp = move.total_pp.to_s
if !move
damage="-"
accuracy="-"
pp="-"
end
textpos = [
[_INTL("Type"), 20, 84, 0, label_base_color, label_shadow_color],
[_INTL("Category"), 20, 116, 0, label_base_color, label_shadow_color],
[_INTL("Power"), 20, 148, 0, label_base_color, label_shadow_color],
[_INTL("{1}", damage), 140, 148, 0, value_base_color, value_shadow_color],
[_INTL("Accuracy"), 20, 180, 0, label_base_color, label_shadow_color],
[_INTL("{1}%", accuracy), 140, 180, 0, value_base_color, value_shadow_color],
[_INTL("PP"), 20, 212, 0, label_base_color, label_shadow_color], #move.total_pp
[_INTL("{1}", pp), 140, 212, 0, value_base_color, value_shadow_color] #move.total_pp
]
imagepos = []
yPos = 90
type_number = GameData::Type.get(move.type).id_number
category = move.category
imagepos.push(["Graphics/Pictures/types", 120, 94, 0, type_number * 28, 64, 28]) #248
imagepos.push(["Graphics/Pictures/category", 120, 124, 0, category * 28, 64, 28])
if !move
imagepos=[]
end
@sprites["overlay"].bitmap.clear
pbDrawTextPositions(@sprites["overlay"].bitmap, textpos)
pbDrawImagePositions(@sprites["overlay"].bitmap, imagepos)
end
def draw_pokemon_type
type1_number = GameData::Type.get(@poke1.type1).id_number
type2_number = GameData::Type.get(@poke1.type2).id_number
type1rect = Rect.new(0, type1_number * 28, 64, 28)
type2rect = Rect.new(0, type2_number * 28, 64, 28)
if @poke1.type1 == @poke1.type2
overlay.blt(130, 78, @typebitmap.bitmap, type1rect)
else
overlay.blt(96, 78, @typebitmap.bitmap, type1rect)
overlay.blt(166, 78, @typebitmap.bitmap, type2rect)
end
end
def updateDescription(index)
index = 0 if !index
begin
move = getMoveForIndex(index)
draw_move_info(move)
new_description = getMoveDescription(move)
@sprites["textbox"].text = _INTL(new_description)
rescue
@sprites["textbox"].text = getDefaultDescription
end
end
def getDefaultDescription
return _INTL("No move selected")
end
def getMoveForIndex(index)
case index
when 0
return @move1
when 1
return @move2
when 2
return @move3
when 3
return @move4
end
return nil
end
def pbFadeInAndShow(sprites, visiblesprites = nil)
return if !@changedColor
super
end
def getMoveName(move)
return " - " if !@sprites["option"] && !move
move = @poke1.moves[@sprites["option"].index] if !move
return GameData::Move.get(move.id).real_name
end
def getMoveDescription(move)
return " - " if !@sprites["option"] && !move
move = @poke1.moves[@sprites["option"].index] if !move
return GameData::Move.get(move.id).real_description
end
def pbGetOptions(inloadscreen = false)
options = [
EnumOption.new(_INTL(""), [_INTL(getMoveName(@poke1.moves[0])), _INTL(getMoveName(@poke2.moves[0]))],
proc { 0 },
proc { |value|
@move1 = value == 0 ? @poke1.moves[0] : @poke2.moves[0]
}, [getMoveDescription(@poke1.moves[0]), getMoveDescription(@poke2.moves[0])]
),
EnumOption.new(_INTL(""), [_INTL(getMoveName(@poke1.moves[1])), _INTL(getMoveName(@poke2.moves[1]))],
proc { 0 },
proc { |value|
@move2 = value == 0 ? @poke1.moves[1] : @poke2.moves[1]
}, [getMoveDescription(@poke1.moves[1]), getMoveDescription(@poke2.moves[1])]
),
EnumOption.new(_INTL(""), [_INTL(getMoveName(@poke1.moves[2])), _INTL(getMoveName(@poke2.moves[2]))],
proc { 0 },
proc { |value|
@move3 = value == 0 ? @poke1.moves[2] : @poke2.moves[2]
}, [getMoveDescription(@poke1.moves[2]), getMoveDescription(@poke2.moves[2])]
),
EnumOption.new(_INTL(""), [_INTL(getMoveName(@poke1.moves[3])), _INTL(getMoveName(@poke2.moves[3]))],
proc { 0 },
proc { |value|
@move4 = value == 0 ? @poke1.moves[3] : @poke2.moves[3]
}, [getMoveDescription(@poke1.moves[3]), getMoveDescription(@poke2.moves[3])]
)
]
return options
end
def isConfirmedOnKeyPress
return true
end
def initOptionsWindow
optionsWindow = Window_PokemonOptionFusionMoves.new(@PokemonOptions, 0,
@sprites["title"].height, Graphics.width,
Graphics.height - @sprites["title"].height - @sprites["textbox"].height)
optionsWindow.viewport = @viewport
optionsWindow.visible = true
return optionsWindow
end
end
class Window_PokemonOptionFusionMoves < Window_PokemonOption
def initialize(options, x, y, width, height)
super
@mustUpdateOptions=true
@mustUpdateDescription=true
@confirmed=false
end
def drawCursor(index,rect)
if self.index==index
pbCopyBitmap(self.contents, @selarrow.bitmap,rect.x+175,rect.y)
end
return Rect.new(rect.x+16,rect.y,rect.width-16,rect.height)
end
def dont_draw_item(index)
return index == @options.length
end
end
@@ -2,6 +2,18 @@ def playerHasFusionItems()
return pbHasItem?(:DNASPLICERS) || pbHasItem?(:SUPERSPLICERS) || pbHasItem?(:INFINITESPLICERS) || pbHasItem?(:INFINITESPLICERS2)
end
def hasUnfusedPokemonInParty(allow_fainted=true)
$Trainer.party.each do |pokemon|
unless pokemon.isFusion?
if !allow_fainted
next if pokemon.hp <= 0
end
return true
end
end
return false
end
def selectSplicer()
dna_splicers_const = _INTL("DNA Splicers")
super_splicers_const = _INTL("Super Splicers")
@@ -22,7 +34,7 @@ def selectSplicer()
return nil
end
cmd = pbShowCommands(_INTL("Use which splicers?"), options)
cmd = pbMessage(_INTL("Use which splicers?"), options)
if cmd == -1
return nil
end
@@ -133,6 +145,14 @@ def get_head_id_from_symbol(id)
return split_id[0].to_i
end
#returns [BODY num, HEAD num]
def splitHeadBody(id)
if (m = id.to_s.match(/\AB(\d+)H(\d+)\z/))
return [m[1].to_i, m[2].to_i]
end
return nil
end
def obtainPokemonSpritePath(id, includeCustoms = true)
head = getBasePokemonID(param.to_i, false)
body = getBasePokemonID(param.to_i, true)
@@ -221,6 +241,7 @@ def checkIfCustomSpriteExistsByPath(path)
return true if pbResolveBitmap(path) != nil
end
def customSpriteExistsBodyHead(body, head)
pathCustom = getCustomSpritePath(body, head)
@@ -260,7 +281,7 @@ end
def getRandomLocalFusion()
spritesList = []
$PokemonGlobal.alt_sprite_substitutions.each_value do |value|
$PokemonSystem.alt_sprite_substitutions.each_value do |value|
if value.is_a?(PIFSprite)
spritesList << value
end
@@ -342,6 +363,8 @@ def getDexNumberForSpecies(species)
dexNum = GameData::Species.get(species.species).id_number
elsif species.is_a?(GameData::Species)
return species.id_number
elsif species.is_a?(String)
dexNum = GameData::Species.get(species).id_number
else
dexNum = species
end
@@ -403,6 +426,7 @@ def get_pokemon_readable_internal_name(pokemon)
end
def get_species_readable_internal_name(species_symbol)
return unless species_symbol
if isSpeciesFusion(species_symbol)
body_pokemon = get_body_species_from_symbol(species_symbol)
head_pokemon = get_head_species_from_symbol(species_symbol)
@@ -1,15 +1,24 @@
class DoublePreviewScreen
attr_reader :sprite_left
attr_reader :sprite_right
SELECT_ARROW_X_LEFT= 100
SELECT_ARROW_X_RIGHT= 350
SELECT_ARROW_X_CANCEL= 230
SELECT_ARROW_Y_SELECT= 0
SELECT_ARROW_Y_CANCEL= 210
ARROW_GRAPHICS_PATH = "Graphics/Pictures/selHand"
CANCEL_BUTTON_PATH = "Graphics/Pictures/previewScreen_Cancel"
ARROW_GRAPHICS_PATH = "Graphics/Pictures/Fusion/selHand"
CANCEL_BUTTON_PATH = "Graphics/Pictures/Fusion/previewScreen_Cancel"
BACKGROUND_PATH = "Graphics/Pictures/shadeFull_"
EVO_BUTTON_PATH = "Graphics/Pictures/Fusion/previewScreen_evolution"
EVO_BUTTON_X= 272
EVO_BUTTON_Y= 4
ICON_EVO_HAS_CUSTOM = "Graphics/Pictures/Fusion/evoCustom"
ICON_EVO_HAS_NO_CUSTOM = "Graphics/Pictures/Fusion/evoNoCustom"
ICON_EVO_FULL_CUSTOM = "Graphics/Pictures/Fusion/evoCustom_full"
CANCEL_BUTTON_X= 140
CANCEL_BUTTON_Y= 260
@@ -26,10 +35,13 @@ class DoublePreviewScreen
@selected = 0
@last_post=0
@sprites = {}
@sprite_right = nil
@selected_sprite = nil
initializeBackground
initializeSelectArrow
initializeCancelButton
initializeEvolutionsButton
hideAllEvoIcons
end
def getBackgroundPicture
@@ -42,12 +54,23 @@ class DoublePreviewScreen
@sprites["cancel"].visible=false
#@sprites["arrow"].visible=false
#todo: il y a un fuck en quelque part.... en attendant ca marche inversé ici
return @species_left if selected == 0
return @species_right if selected == 1
if selected == 0
@selected_sprite = @sprite_left
return @species_left
end
if selected == 1
@selected_sprite = @sprite_right
return @species_right
end
return -1
end
def get_selected_sprite
return @selected_sprite
end
def startSelection
loop do
Graphics.update
@@ -71,20 +94,50 @@ class DoublePreviewScreen
end
def updateSelectionIndex
if Input.trigger?(Input::LEFT)
@selected = 0
elsif Input.trigger?(Input::RIGHT)
@selected = 1
end
@up_hold_frames ||= 0
if @selected == -1
@up_hold_frames = 0
if Input.trigger?(Input::UP)
@selected = @last_post
end
else
if Input.trigger?(Input::DOWN)
if Input.trigger?(Input::LEFT)
@selected = 0
elsif Input.trigger?(Input::RIGHT)
@selected = 1
elsif Input.trigger?(Input::DOWN)
@last_post = @selected
@selected = -1
end
if Input.press?(Input::UP) && @selected > -1
@up_hold_frames += 1
showAllEvoIcons if @up_hold_frames >= 6
else
@up_hold_frames = 0
hideAllEvoIcons
end
end
end
def hideAllEvoIcons
@sprites["evo"].visible=true
@evo_icons_visible = false
@sprites.each do |key, sprite|
sprite.visible = false if key.start_with?("evo_icon_")
end
end
def showAllEvoIcons
@sprites["evo"].visible=false
unless @evo_icons_visible
pbSEPlay("GUI storage show party panel")
@evo_icons_visible = true
end
@sprites.each do |key, sprite|
sprite.visible = true if key.start_with?("evo_icon_")
end
end
@@ -102,7 +155,7 @@ class DoublePreviewScreen
pbUpdateSpriteHash(@sprites)
end
def draw_window(dexNumber, level, x, y, isShiny=false, bodyShiny = false, headShiny=false)
def draw_window(dexNumber, level, x, y, isShiny=false, bodyShiny = false, headShiny=false, window_position=0)
body_pokemon = getBodyID(dexNumber)
head_pokemon = getHeadID(dexNumber, body_pokemon)
@@ -115,13 +168,22 @@ class DoublePreviewScreen
bitmap.scale_bitmap(Settings::FRONTSPRITE_SCALE)
pif_sprite = spriteLoader.obtain_fusion_pif_sprite(head_pokemon,body_pokemon)
#hasCustom = picturePath.include?("CustomBattlers")
#hasCustom = customSpriteExistsBase(body_pokemon,head_pokemon)
if window_position == 0
@sprite_left = pif_sprite
else
@sprite_right = pif_sprite
end
hasCustom = customSpriteExists(body_pokemon,head_pokemon)
@viewport_evo = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport_evo.z = 100001
drawEvolutionIcons(dexNumber, @viewport_evo, x+16, y + 12, window_position)
previewwindow = PictureWindow.new(bitmap)
previewwindow.x = x
previewwindow.y = y
previewwindow.z = 100000
previewwindow.z = 99999
drawFusionInformation(dexNumber, level, x)
@@ -138,6 +200,67 @@ class DoublePreviewScreen
end
def drawEvolutionIcons(dexNumber, viewport, x, y, window_position)
current_species = GameData::Species.get(dexNumber)
if current_species.is_fusion
body_num = getBodyID(current_species.id_number)
head_num = getHeadID(current_species.id_number, body_num)
body_chain = GameData::Species.get(body_num).get_ordered_family_species
head_chain = GameData::Species.get(head_num).get_ordered_family_species
ordered_species = []
seen = {}
body_chain.each do |body_sp|
head_chain.each do |head_sp|
body_dex = getDexNumberForSpecies(body_sp)
head_dex = getDexNumberForSpecies(head_sp)
fused_id = getFusedPokemonIdFromDexNum(body_dex, head_dex)
next if seen[fused_id]
next unless GameData::Species.get(fused_id)
seen[fused_id] = true
ordered_species << fused_id
end
end
else
ordered_species = current_species.get_ordered_family_species
end
current_species_index = ordered_species.index(current_species.species) || 0
parsed_species = []
evolution_customs = []
ordered_species.each do |species|
next if parsed_species.include?(species)
parsed_species << species
evolution_customs << customSpriteExistsSpecies(species)
end
return if evolution_customs.empty?
icon_width = 16
icon_spacing = 4
max_per_row = 10
row_height = icon_width + 4
rows = evolution_customs.each_slice(max_per_row).to_a
rows.each_with_index do |row_customs, row_index|
start_x = x + icon_spacing
row_y = y + (row_index * row_height)
row_customs.each_with_index do |has_custom, col_index|
global_index = (row_index * max_per_row) + col_index
icon_path = has_custom ? ICON_EVO_HAS_CUSTOM : ICON_EVO_HAS_NO_CUSTOM
icon_path += "_selected" if global_index == current_species_index
icon_bitmap = AnimatedBitmap.new(icon_path).bitmap
icon_sprite = Sprite.new(viewport)
icon_sprite.bitmap = icon_bitmap
icon_sprite.x = start_x + (col_index * (icon_width + icon_spacing))
icon_sprite.y = row_y
icon_sprite.z = 10000
@sprites["evo_icon_#{window_position}_#{global_index}"] = icon_sprite
end
end
end
def drawFusionInformation(fusedDexNum, level, x = 0)
viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@typewindows << drawPokemonType(fusedDexNum, viewport, x + 55, 220) if @draw_types
@@ -154,6 +277,13 @@ class DoublePreviewScreen
@sprites["arrow"].z = 100001
end
def initializeEvolutionsButton()
@sprites["evo"] = IconSprite.new(0, 0, @viewport)
@sprites["evo"].setBitmap(EVO_BUTTON_PATH)
@sprites["evo"].x = EVO_BUTTON_X
@sprites["evo"].y = EVO_BUTTON_Y
@sprites["evo"].z = 100000
end
def initializeCancelButton()
@sprites["cancel"] = IconSprite.new(0, 0, @viewport)
@@ -205,7 +335,7 @@ class DoublePreviewScreen
overlay = BitmapSprite.new(Graphics.width, Graphics.height, viewport).bitmap
pokemon = GameData::Species.get(pokemon_id)
typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
typebitmap = AnimatedBitmap.new("Graphics/Pictures/types")
type1_number = GameData::Type.get(pokemon.type1).id_number
type2_number = GameData::Type.get(pokemon.type2).id_number
type1rect = Rect.new(0, type1_number * 28, 64, 28)
@@ -37,15 +37,15 @@ class FusionSelectOptionsScene < PokemonOption_Scene
def getAbilityName(ability)
return GameData::Ability.get(ability.id).real_name
return GameData::Ability.get(ability.id).name
end
def getAbilityDescription(ability)
return GameData::Ability.get(ability.id).real_description
return GameData::Ability.get(ability.id).description
end
def getNatureName(nature)
return GameData::Nature.get(nature.id).real_name
return GameData::Nature.get(nature.id).name
end
def getNatureDescription(nature)
@@ -106,6 +106,19 @@ class FusionSelectOptionsScene < PokemonOption_Scene
return options
end
#Same as Option, but without pbRefreshSceneMap
def pbEndScene
pbPlayCloseMenuSE
pbFadeOutAndHide(@sprites) { pbUpdate }
# Set the values of each option
for i in 0...@PokemonOptions.length
@PokemonOptions[i].set(@sprites["option"][i])
end
pbDisposeMessageWindow(@sprites["textbox"])
pbDisposeSpriteHash(@sprites)
@viewport.dispose
end
def isConfirmedOnKeyPress
return true
@@ -0,0 +1,584 @@
class FusionMovesOptionsScene < PokemonOption_Scene
attr_reader :all_moves
attr_reader :selected_moves
attr_reader :move_slots
def initialize(poke1, poke2)
@poke1 = poke1
@poke2 = poke2
@fused_pokemon = @poke1
@head_species = @fused_pokemon.species_data.head_pokemon
@body_species = @fused_pokemon.species_data.body_pokemon
@selected_moves = []
@index_vertical = 0
@index_horizontal = 0
@selBaseColor = Color.new(48, 96, 216)
@selShadowColor = Color.new(32, 32, 32)
@counterBaseColor = pbColor(:LIGHT_TEXT_MAIN_COLOR)
@counterShadowColor = pbColor(:LIGHT_TEXT_SHADOW_COLOR)
@counterFullBaseColor = pbColor(:GREEN)
@counterFullShadowColor = pbColor(:DARKGREEN)
@maxMovesNb = [listUniqueAvailableMoves.length, 4].min
end
def initUIElements
Kernel.pbClearText()
@sprites["pokeicon_fused"] = PokemonIconSprite.new(@fused_pokemon.species, @viewport)
@sprites["pokeicon_fused"].x = 12
@sprites["pokeicon_fused"].y = 0
@sprites["titleMsg"] = Window_UnformattedTextPokemon.newWithSize(
_INTL("Select the moves you want to keep"), 64, 0, Graphics.width, 64, @viewport)
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(_INTL(""), 0, 32, Graphics.width, 64, @viewport)
@sprites["textbox"] = pbCreateMessageWindow
@sprites["textbox"].letterbyletter = false
@sprites["textbox"].height = @sprites["textbox"].height + 24
@sprites["textbox"].y = @sprites["textbox"].y - 24
@sprites["textbox"].baseColor = Color.new(64, 64, 64) # dark gray text
@sprites["textbox"].shadowColor = Color.new(168, 168, 168) # lighter shadow
if isDarkMode
@sprites["textbox"].baseColor, @sprites["textbox"].shadowColor = @sprites["textbox"].shadowColor, @sprites["textbox"].baseColor
end
addBackgroundPlane(@sprites, "bg_moves", "Fusion/movesOverlay", @viewport)
addBackgroundPlane(@sprites, "bg_stats", "Fusion/statsOverlay", @viewport)
@sprites["bg_stats"].visible = false
@sprites["counter"] = Window_UnformattedTextPokemon.newWithSize(
_INTL("0 / {1}", @maxMovesNb), 386, 226, Graphics.width, 84, @viewport)
@sprites["counter"].setSkin("Graphics/Windowskins/invisible")
showPokemonIcons
pbSetSystemFont(@sprites["textbox"].contents)
end
def updateCounter
count = @selected_moves.length
@sprites["counter"].text = _INTL("{1} / {2}", count, @maxMovesNb)
if count == @maxMovesNb
@sprites["counter"].baseColor = @counterFullBaseColor
@sprites["counter"].shadowColor = @counterFullShadowColor
else
@sprites["counter"].baseColor = @counterBaseColor
@sprites["counter"].shadowColor = @counterShadowColor
end
end
def getSelectedMoves
return @selected_moves
end
CURSOR_X_OFFSET = 8
CURSOR_Y_OFFSET = 16
def showPokemonIcons
@sprites["pokeicon_1"] = PokemonIconSprite.new(@head_species.species, @viewport)
@sprites["pokeicon_1"].x = 264
@sprites["pokeicon_1"].y = 50
@sprites["pokeicon_2"] = PokemonIconSprite.new(@body_species.species, @viewport)
@sprites["pokeicon_2"].x = 388
@sprites["pokeicon_2"].y = 50
@sprites["pokecursor"] = IconSprite.new(0, 0, @viewport)
@sprites["pokecursor"].setBitmap("Graphics/Pictures/Fusion/cursor")
@sprites["pokecursor"].x = @sprites["pokeicon_1"].x + CURSOR_X_OFFSET
@sprites["pokecursor"].y = @sprites["pokeicon_1"].y + CURSOR_Y_OFFSET
@sprites["pokecursor"].visible = true
end
def pbStartScene(inloadscreen = false)
super
@typebitmap = AnimatedBitmap.new("Graphics/Pictures/types")
@sprites["overlay"] = BitmapSprite.new(Graphics.width, Graphics.height, @viewport)
@sprites["overlay"].z = 9999
pbSetSystemFont(@sprites["overlay"].bitmap)
@sprites["option"].nameBaseColor = MessageConfig::BLUE_TEXT_MAIN_COLOR
@sprites["option"].nameShadowColor = MessageConfig::BLUE_TEXT_SHADOW_COLOR
@changedColor = true
for i in 0...@PokemonOptions.length
@sprites["option"][i] = (@PokemonOptions[i].get || 0)
end
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(_INTL(""), 0, 66, Graphics.width, 64, @viewport)
@sprites["title"].setSkin("Graphics/Windowskins/invisible")
@sprites["option"].setSkin("Graphics/Windowskins/invisible")
# echoln @sprites["option"].bitmap.text_size
# @sprites["option"].bitmap.text_size=10
updatePokemonCursor(0)
updateDescription(0)
updateCounter
pbFadeInAndShow(@sprites) { pbUpdate }
end
def getOptionsWidth(rect)
width = super(rect)
return width + 24
end
def draw_move_info(pokemonMove)
@sprites["bg_stats"].visible = false
@sprites["bg_moves"].visible = true
move = GameData::Move.get(pokemonMove.id)
label_base_color = Color.new(248, 248, 248)
label_shadow_color = Color.new(104, 104, 104)
value_base_color = Color.new(248, 248, 248)
value_shadow_color = Color.new(104, 104, 104)
@sprites["title"].text = _INTL("{1}", move.name)
damage = move.base_damage == 0 ? "-" : move.base_damage.to_s
accuracy = move.accuracy == 0 ? "100" : move.accuracy.to_s
pp = move.total_pp.to_s
if !move
damage = "-"
accuracy = "-"
pp = "-"
end
start_y = 110
gap_height = 32
textpos = [
[_INTL("Type"), 20, start_y, 0, label_base_color, label_shadow_color],
[_INTL("Category"), 20, start_y + (gap_height * 1), 0, label_base_color, label_shadow_color],
[_INTL("Power"), 20, start_y + (gap_height * 2), 0, label_base_color, label_shadow_color],
["#{damage}", 148, start_y + (gap_height * 2), 0, value_base_color, value_shadow_color],
[_INTL("Accuracy"), 20, start_y + (gap_height * 3), 0, label_base_color, label_shadow_color],
["#{accuracy}%", 148, start_y + (gap_height * 3), 0, value_base_color, value_shadow_color],
[_INTL("PP"), 20, start_y + (gap_height * 4), 0, label_base_color, label_shadow_color],
["#{pp}", 148, start_y + (gap_height * 4), 0, value_base_color, value_shadow_color]
]
imagepos = []
type_number = GameData::Type.get(move.type).id_number
category = move.category
imagepos.push(["Graphics/Pictures/types", 140, start_y + (gap_height * 0) + 8, 0, type_number * 28, 64, 28])
imagepos.push(["Graphics/Pictures/category", 140, start_y + (gap_height * 1) + 8, 0, category * 28, 64, 28])
if !move
imagepos = []
end
@sprites["overlay"].bitmap.clear
pbDrawTextPositions(@sprites["overlay"].bitmap, textpos)
pbDrawImagePositions(@sprites["overlay"].bitmap, imagepos)
end
def draw_pokemon_info
@sprites["bg_stats"].visible = true
@sprites["bg_moves"].visible = false
label_base_color = Color.new(248, 248, 248)
label_shadow_color = Color.new(104, 104, 104)
value_base_color = Color.new(248, 248, 248)
value_shadow_color = Color.new(104, 104, 104)
@sprites["title"].text = ""
start_y = 78
gap_height = 32
textpos = [
[_INTL("HP"), 20, start_y, 0, label_base_color, label_shadow_color],
[_INTL("{1}", @fused_pokemon.totalhp), 158, start_y, 0, label_base_color, label_shadow_color],
[_INTL("Attack"), 20, start_y + (gap_height * 1), 0, label_base_color, label_shadow_color],
[_INTL("{1}", @fused_pokemon.attack), 158, start_y + (gap_height * 1), 0, label_base_color, label_shadow_color],
[_INTL("Defense"), 20, start_y + (gap_height * 2), 0, label_base_color, label_shadow_color],
[_INTL("{1}", @fused_pokemon.defense), 158, start_y + (gap_height * 2), 0, label_base_color, label_shadow_color],
[_INTL("Sp. Attack"), 20, start_y + (gap_height * 3), 0, label_base_color, label_shadow_color],
[_INTL("{1}", @fused_pokemon.spatk), 158, start_y + (gap_height * 3), 0, value_base_color, value_shadow_color],
[_INTL("Sp. Defense"), 20, start_y + (gap_height * 4), 0, label_base_color, label_shadow_color],
[_INTL("{1}", @fused_pokemon.spdef), 158, start_y + (gap_height * 4), 0, value_base_color, value_shadow_color],
[_INTL("Speed"), 20, start_y + (gap_height * 5), 0, label_base_color, label_shadow_color],
[_INTL("{1}", @fused_pokemon.speed), 158, start_y + (gap_height * 5), 0, value_base_color, value_shadow_color],
]
@sprites["overlay"].bitmap.clear
pbDrawTextPositions(@sprites["overlay"].bitmap, textpos)
end
# def draw_pokemon_type
# type1_number = GameData::Type.get(@poke1.type1).id_number
# type2_number = GameData::Type.get(@poke1.type2).id_number
# type1rect = Rect.new(0, type1_number * 28, 64, 28)
# type2rect = Rect.new(0, type2_number * 28, 64, 28)
# if @poke1.type1 == @poke1.type2
# overlay.blt(130, 78, @typebitmap.bitmap, type1rect)
# else
# overlay.blt(96, 78, @typebitmap.bitmap, type1rect)
# overlay.blt(166, 78, @typebitmap.bitmap, type2rect)
# end
# end
def updatePokemonCursor(index)
index = 0 if !index
if @sprites["pokecursor"]
if index == 0
highlighted_value = @sprites["option"] ? (@sprites["option"][0] || 0) : 0
@sprites["pokecursor"].visible = true
@sprites["pokecursor"].x = highlighted_value == 0 ? @sprites["pokeicon_1"].x : @sprites["pokeicon_2"].x
@sprites["pokecursor"].y = highlighted_value == 0 ? @sprites["pokeicon_1"].y : @sprites["pokeicon_2"].y
@sprites["pokecursor"].x += CURSOR_X_OFFSET
@sprites["pokecursor"].y += CURSOR_Y_OFFSET
else
@sprites["pokecursor"].visible = false
end
end
end
def pbUpdate
pbUpdateSpriteHash(@sprites)
if @sprites["option"].mustUpdateDescription || @sprites["option"].mustUpdateOptions
updatePokemonCursor(@sprites["option"].index)
updateDescription(@sprites["option"].index)
@sprites["option"].descriptionUpdated
end
end
def updateDescription(index)
index = 0 if !index
begin
return if !@move_slots
col = @sprites["option"] ? (@sprites["option"][index] || 0) : 0
if index == 0
# Header row — show pokemon info panel
draw_pokemon_info
species = col == 0 ? @head_species : @body_species
@sprites["textbox"].text = _INTL("\nSelect all moves from {1}", GameData::Species.get(species).name)
return
end
slot = @move_slots[index - 1]
return if !slot
move = slot[col]
if move
draw_move_info(move)
@sprites["textbox"].text = _INTL(getMoveDescription(move))
else
@sprites["overlay"].bitmap.clear
@sprites["textbox"].text = getDefaultDescription
end
rescue => e
@sprites["textbox"].text = getDefaultDescription
end
end
def getDefaultDescription
return _INTL("No move selected")
end
def getMoveForIndex(index)
# Offset by 1 to skip the all moves button
move_index = index - 1
return nil if move_index < 0
highlighted_value = @sprites["option"] ? (@sprites["option"][index] || 0) : 0
case move_index
when 0 then highlighted_value == 0 ? @poke1.moves[0] : @poke2.moves[0]
when 1 then highlighted_value == 0 ? @poke1.moves[1] : @poke2.moves[1]
when 2 then highlighted_value == 0 ? @poke1.moves[2] : @poke2.moves[2]
when 3 then highlighted_value == 0 ? @poke1.moves[3] : @poke2.moves[3]
end
end
def listUniqueAvailableMoves
moves = []
moves += @poke1.moves
moves += @poke2.moves
return moves.uniq { |m| m.id }
end
def pbFadeInAndShow(sprites, visiblesprites = nil)
return if !@changedColor
super
end
def getMoveName(move)
return " - " if !@sprites["option"] && !move
move = @poke1.moves[@sprites["option"].index] if !move
return GameData::Move.get(move.id).name
end
def getMoveDescription(move)
return " - " if !@sprites["option"] && !move
move = @poke1.moves[@sprites["option"].index] if !move
return GameData::Move.get(move.id).description
end
def pbGetOptions(inloadscreen = false)
@move_slots = (0..3).map { |i| [@poke2.moves[i], @poke1.moves[i]] }
# Row 0: the "select all" header row
header = EnumOption.new(
"",
["", ""],
proc { 0 },
proc {},
["", ""]
)
move_options = @move_slots.map do |slot|
left_name = slot[0] ? GameData::Move.get(slot[0].id).name : "-"
right_name = slot[1] ? GameData::Move.get(slot[1].id).name : "-"
EnumOption.new(
"",
[left_name, right_name],
proc { 0 },
proc {},
["", ""]
)
end
return [header] + move_options
end
def pbOptions
pbActivateWindow(@sprites, "option") {
loop do
Graphics.update
Input.update
pbUpdate
if @sprites["option"].mustUpdateOptions
for i in 0...@PokemonOptions.length
@PokemonOptions[i].set(@sprites["option"][i])
end
end
@index_vertical = @sprites["option"].index
@index_horizontal = @sprites["option"][@index_vertical] || 0
if Input.trigger?(Input::USE)
# Confirm
if @index_vertical == @PokemonOptions.length
if @selected_moves.length > 0 && validateSelectedMoves
echoln @maxMovesNb
if @selected_moves.length < @maxMovesNb && listUniqueAvailableMoves.length > @selected_moves.length
nb_more = @maxMovesNb - @selected_moves.length
plural_s = nb_more > 1 ? "s" : ""
if pbConfirmMessage(_INTL("You can still select \\C[1]{1}\\C[0] additional move{2}. Are you sure you want to continue?", nb_more, plural_s))
break
end
else
break
end
else
pbPlayBuzzerSE
end
next
end
# Select all
if @index_vertical == 0
col = @index_horizontal
@selected_moves = @move_slots.map { |slot| slot[col] }.compact
(0...@PokemonOptions.length).each { |i| @sprites["option"].setValueNoRefresh(i, col) }
@sprites["option"].refresh
pbSEPlay("GUI naming confirm")
updateCounter
updateDescription(@index_vertical)
# Auto-jump to Confirm
@sprites["option"].index = @PokemonOptions.length
@sprites["option"].refresh
updateCounter
updatePokemonCursor(@PokemonOptions.length)
next
end
# Individual move row (rows 1-4, slot index is vertical - 1)
slot_index = @index_vertical - 1
move = @move_slots[slot_index][@index_horizontal]
next if !move
already_selected = @selected_moves.any? { |m| m.id == move.id }
if already_selected
@selected_moves.reject! { |m| m.id == move.id }
else
if @selected_moves.length >= 4
pbPlayBuzzerSE
else
@selected_moves << move
# Auto-jump to Confirm when 4th move is selected
if @selected_moves.length == @maxMovesNb
pbSEPlay("GUI naming confirm")
(0...@PokemonOptions.length).each { |i| @sprites["option"].setValueNoRefresh(i, @sprites["option"][@index_vertical] || 0) }
@sprites["option"].index = @PokemonOptions.length
@sprites["option"].refresh
updatePokemonCursor(@PokemonOptions.length)
end
end
end
@sprites["option"].refresh
updateCounter
updateDescription(@index_vertical)
end
end
}
end
def set_all_moves_to_index(index)
[1, 2, 3, 4].each { |i| @sprites["option"][i] = index }
source = index == 0 ? @poke1 : @poke2
@move1 = source.moves[0]
@move2 = source.moves[1]
@move3 = source.moves[2]
@move4 = source.moves[3]
@sprites["option"].refresh
updatePokemonCursor(@sprites["option"].index)
updateCounter
updateDescription(@sprites["option"].index)
end
def isConfirmedOnKeyPress
return false
end
def initOptionsWindow
x_pos = 0
y_pos = @sprites["title"].height
item_height = 32 # standard row height in Essentials
num_items = @PokemonOptions.length + 1 # +1 for Confirm
window_height = item_height * num_items + 4 # +4 for border padding
optionsWindow = Window_PokemonOptionFusionMoves.new(@PokemonOptions, x_pos, y_pos, Graphics.width,
window_height + 32,
self)
optionsWindow.viewport = @viewport
optionsWindow.visible = true
return optionsWindow
end
def validateSelectedMoves
return @selected_moves.length > 0 && @selected_moves.length <= 4
end
#Same as Option, but without pbRefreshSceneMap
def pbEndScene
pbPlayCloseMenuSE
pbFadeOutAndHide(@sprites) { pbUpdate }
# Set the values of each option
for i in 0...@PokemonOptions.length
@PokemonOptions[i].set(@sprites["option"][i])
end
pbDisposeMessageWindow(@sprites["textbox"])
pbDisposeSpriteHash(@sprites)
@viewport.dispose
end
end
class Window_PokemonOptionFusionMoves < Window_PokemonOption
OPTIONS_X_OFFSET = 0
COLUMNS_GAP = 20
def initialize(options, x, y, width, height, scene)
@scene = scene
super(options, x, y, width, height)
@mustUpdateOptions = true
@mustUpdateDescription = true
@confirmed = false
end
def drawCursor(index, rect)
if self.index == index
unless index == 0
optionwidth = rect.width * 9 / 20
col = self[index] || 0
if @options[index].is_a?(EnumOption) && @options[index].values.length > 1
col0_x = optionwidth + rect.x + 12 + OPTIONS_X_OFFSET
col1_x = col0_x + (rect.width - col0_x) / 2 + COLUMNS_GAP
xpos = col == 0 ? col0_x : col1_x
arrow_x = xpos - @selarrow.bitmap.width - 2
else
arrow_x = rect.x + 175
end
pbCopyBitmap(self.contents, @selarrow.bitmap, arrow_x, rect.y)
end
end
return Rect.new(rect.x + 16, rect.y, rect.width - 16, rect.height)
end
def drawItem(index, _count, rect)
return if dont_draw_item(index)
rect = drawCursor(index, rect)
if index == @options.length
optionwidth = rect.width * 9 / 20
base_color = Color.new(
[@nameBaseColor.red + 80, 255].min,
[@nameBaseColor.green + 80, 255].min,
[@nameBaseColor.blue + 80, 255].min
)
shadow_color = Color.new(
[base_color.red - 60, 0].max,
[base_color.green - 60, 0].max,
[base_color.blue - 60, 0].max
)
pbDrawShadowText(self.contents, 216, rect.y, optionwidth, rect.height,
_INTL(" Confirm"), base_color, shadow_color)
return
end
return unless @options[index].is_a?(EnumOption) && @options[index].values.length > 1
optionwidth = rect.width * 9 / 20
col0_x = optionwidth + rect.x + 12 + OPTIONS_X_OFFSET
col1_x = col0_x + (rect.width - col0_x) / 2 + COLUMNS_GAP
col_width = col1_x - col0_x - COLUMNS_GAP
@options[index].values.each_with_index do |value, col|
slot_index = index - 1
move = slot_index >= 0 ? @scene.move_slots&.[](slot_index)&.[](col) : nil
is_selected = move && @scene.selected_moves.any? { |m| m.id == move.id }
base = is_selected ? @selBaseColor : Color.new(180, 180, 180)
shadow = is_selected ? @selShadowColor : Color.new(80, 80, 80)
xpos = col == 0 ? col0_x : col1_x
pbDrawShadowText(self.contents, xpos, rect.y, col_width, rect.height, value, base, shadow)
end
end
def dont_draw_item(index)
return false
# return index == @options.length
end
def update
old_index = self.index
super
if self.index != old_index && self.index < @options.length
if old_index < @options.length
@optvalues[self.index] = @optvalues[old_index]
else
# Coming from confirm -> go to unselected one (makes it easier to quickly swap between the two)
current = @optvalues[self.index] || 0
@optvalues[self.index] = current == 0 ? 1 : 0
end
refresh
end
end
end
@@ -36,8 +36,8 @@ class FusionPreviewScreen < DoublePreviewScreen
fusion_left = (poke1.species_data.id_number) * NB_POKEMON + poke2.species_data.id_number
fusion_right = (poke2.species_data.id_number) * NB_POKEMON + poke1.species_data.id_number
@picture1 = draw_window(fusion_left,new_level,20,30,shiny,poke1_shiny,poke2_shiny)
@picture2 = draw_window(fusion_right,new_level,270,30,shiny,poke2_shiny,poke1_shiny)
@picture1 = draw_window(fusion_left,new_level,20,30,shiny,poke1_shiny,poke2_shiny,0)
@picture2 = draw_window(fusion_right,new_level,270,30,shiny,poke2_shiny,poke1_shiny,1)
@sprites["picture1"] = @picture1
@sprites["picture2"] = @picture2
@@ -29,7 +29,12 @@ class AutogenExtracter < PIFSpriteExtracter
def getSpritesheetPath(pif_sprite)
head_id = pif_sprite.head_id
return "#{SPRITESHEET_FOLDER_PATH}#{head_id}.png"
return getSpritesheetPathFromId(head_id)
end
def getSpritesheetPathFromId(head_id)
filename = head_id.to_s + ".png"
return "#{SPRITESHEET_FOLDER_PATH}#{filename}"
end
def get_resize_scale
@@ -66,7 +71,7 @@ class AutogenExtracter < PIFSpriteExtracter
start_time = Time.now
head_id = pif_sprite.head_id
body_id = pif_sprite.body_id
spritesheet_file = "#{SPRITESHEET_FOLDER_PATH}#{head_id}.png"
spritesheet_file = getSpritesheetPathFromId(head_id)
# Check cache before loading from disk
spritesheet_bitmap = @@spritesheet_cache.fetch(spritesheet_file) do
@@ -4,15 +4,20 @@ class BattleSpriteLoader
end
def load_pif_sprite_directly(pif_sprite)
if pif_sprite.local_path && pbResolveBitmap(pif_sprite.local_path)
if pif_sprite&.local_path && pbResolveBitmap(pif_sprite.local_path)
return AnimatedBitmap.new(pif_sprite.local_path)
end
extractor = get_sprite_extractor_instance(pif_sprite.type)
return extractor.load_sprite(pif_sprite)
bitmap = extractor.load_sprite(pif_sprite)
if bitmap
return bitmap
else
return handle_unloaded_sprites(extractor, pif_sprite)
end
end
#random alt
def load_pif_sprite(pif_sprite)
def load_random_alt_for_pif_sprite(pif_sprite)
case pif_sprite.type
when :CUSTOM, :AUTOGEN
load_fusion_sprite(pif_sprite.head_id, pif_sprite.body_id)
@@ -26,8 +31,8 @@ class BattleSpriteLoader
return if !pokemon
substitution_id = get_sprite_substitution_id_from_dex_number(pokemon.species)
# echoln substitution_id
# echoln $PokemonGlobal.alt_sprite_substitutions
pif_sprite = $PokemonGlobal.alt_sprite_substitutions[substitution_id] if $PokemonGlobal
# echoln $PokemonSystem.alt_sprite_substitutions
pif_sprite = $PokemonSystem.alt_sprite_substitutions[substitution_id] if $PokemonGlobal
if !pif_sprite
pif_sprite = get_pif_sprite_from_species(pokemon.species)
end
@@ -40,7 +45,7 @@ class BattleSpriteLoader
echoln "preloading"
previous_download_allowed = @download_allowed
@download_allowed = false
load_pif_sprite(pif_sprite)
load_random_alt_for_pif_sprite(pif_sprite)
@download_allowed = previous_download_allowed
end
@@ -67,14 +72,27 @@ class BattleSpriteLoader
def registerSpriteSubstitution(pif_sprite)
substitution_id = get_sprite_substitution_id_from_dex_number(pif_sprite.species)
$PokemonGlobal.alt_sprite_substitutions[substitution_id] = pif_sprite
$PokemonSystem.alt_sprite_substitutions[substitution_id] = pif_sprite
end
def obtain_pif_sprite(species)
species_data = GameData::Species.get(species)
if species_data.is_triple_fusion
pif_sprite = select_new_pif_triple_sprite(species_data.id_number)
elsif species_data.is_fusion
head= species_data.get_head_species
body = species_data.get_body_species
pif_sprite = select_new_pif_fusion_sprite(head, body)
else
pif_sprite = select_new_pif_base_sprite(species_data.id_number)
end
return pif_sprite
end
def obtain_fusion_pif_sprite(head_id,body_id)
substitution_id = get_sprite_substitution_id_for_fusion(head_id, body_id)
pif_sprite = $PokemonGlobal.alt_sprite_substitutions[substitution_id] if $PokemonGlobal
pif_sprite = $PokemonSystem.alt_sprite_substitutions[substitution_id] if $PokemonGlobal
#pif_sprite.dump_info if pif_sprite
if !pif_sprite
if !pif_sprite || $PokemonSystem.random_sprites
pif_sprite = select_new_pif_fusion_sprite(head_id, body_id)
local_path = check_for_local_sprite(pif_sprite)
if local_path
@@ -82,7 +100,7 @@ class BattleSpriteLoader
pif_sprite.type = :CUSTOM
end
substitution_id = get_sprite_substitution_id_for_fusion(head_id, body_id)
$PokemonGlobal.alt_sprite_substitutions[substitution_id] = pif_sprite if $PokemonGlobal
$PokemonSystem.alt_sprite_substitutions[substitution_id] = pif_sprite if $PokemonGlobal && !$PokemonSystem.random_sprites
end
return pif_sprite
end
@@ -103,10 +121,10 @@ class BattleSpriteLoader
def load_base_sprite(dex_number)
substitution_id = get_sprite_substitution_id_from_dex_number(dex_number)
pif_sprite = $PokemonGlobal.alt_sprite_substitutions[substitution_id] if $PokemonGlobal
if !pif_sprite
pif_sprite = $PokemonSystem.alt_sprite_substitutions[substitution_id] if $PokemonGlobal
if !pif_sprite || $PokemonSystem.random_sprites
pif_sprite = select_new_pif_base_sprite(dex_number)
$PokemonGlobal.alt_sprite_substitutions[substitution_id] = pif_sprite if $PokemonGlobal
$PokemonSystem.alt_sprite_substitutions[substitution_id] = pif_sprite if $PokemonGlobal && !$PokemonSystem.random_sprites
end
if pif_sprite.local_path
return AnimatedBitmap.new(pif_sprite.local_path)
@@ -119,6 +137,15 @@ class BattleSpriteLoader
return loaded_sprite
end
def load_pif_sprite_pokemon(pokemon)
pif_sprite = pokemon.pif_sprite
unless pokemon.pif_sprite
pif_sprite = GameData::Species.front_pif_sprite(pokemon.species, pokemon.shiny?, pokemon.body_shiny, pokemon.head_shiny)
pokemon.pif_sprite = pif_sprite
end
return load_pif_sprite_directly(pif_sprite)
end
def handle_unloaded_sprites(extractor,pif_sprite)
if(extractor.is_a?(CustomSpriteExtracter)) #Custom failed to load, load an autogen (which should always be there)
new_extractor = get_sprite_extractor_instance(:AUTOGEN)
@@ -162,7 +189,7 @@ class BattleSpriteLoader
def get_pif_sprite_from_species(species)
substitution_id = get_sprite_substitution_id_from_dex_number(species)
pif_sprite = $PokemonGlobal.alt_sprite_substitutions[substitution_id] if $PokemonGlobal
pif_sprite = $PokemonSystem.alt_sprite_substitutions[substitution_id] if $PokemonGlobal
return pif_sprite if pif_sprite
species_data = GameData::Species.get(species)
if species_data.id_number <= NB_POKEMON #base pokemon
@@ -172,6 +199,15 @@ class BattleSpriteLoader
end
end
def select_new_pif_triple_sprite(dex_number)
sprite= PIFSprite.new(:TRIPLE, dex_number, nil, "")
sprite.local_path = getSpecialSpriteName(dex_number)
echoln sprite.local_path
return sprite
end
#
# Flow:
# # if none found in cache, look for custom sprite in custom spritesheet (download if can't find spritesheet or new spritepack released)
@@ -204,6 +240,8 @@ class BattleSpriteLoader
#todo refactor by using get_triple_fusion_components()
def getSpecialSpriteName(dexNum)
base_path = "Graphics/Battlers/special/"
echoln dexNum
echoln Settings::ZAPMOLCUNO_NB + 31
case dexNum
when Settings::ZAPMOLCUNO_NB
return sprintf(base_path + "144.145.146")
@@ -250,7 +288,7 @@ class BattleSpriteLoader
when Settings::ZAPMOLCUNO_NB + 20 #birdBoss Left
return sprintf(base_path +"invisible")
when Settings::ZAPMOLCUNO_NB + 21 #birdBoss middle
return sprintf(base_path + "144.145.146")
return sprintf(base_path + "BIRDBOSS")
when Settings::ZAPMOLCUNO_NB + 22 #birdBoss right
return sprintf(base_path +"invisible")
when Settings::ZAPMOLCUNO_NB + 23 #sinnohboss left
@@ -272,6 +310,14 @@ class BattleSpriteLoader
return sprintf(base_path + "480.483.486")
when Settings::ZAPMOLCUNO_NB + 30
return sprintf(base_path + "481.484.487")
when Settings::ZAPMOLCUNO_NB + 31 #TELEMAUV
return sprintf(base_path + "000")
when Settings::ZAPMOLCUNO_NB + 32 #Minior/Solrock/Lunatone (meteor)
return sprintf(base_path + "498.544.545")
when Settings::ZAPMOLCUNO_NB + 33 #Minior/Solrock/Lunatone (core)
return sprintf(base_path + "499.544.545")
when Settings::ZAPMOLCUNO_NB + 34 #Stunfisk, bruxish, luvdisc
return sprintf(base_path + "420.469.501")
else
return sprintf(base_path + "000")
end
@@ -4,22 +4,24 @@ module GameData
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) if ret #for pokemon with size differences
ret = front_sprite_bitmap_pokemon(pkmn)
# if back
# ret = front_sprite_bitmap(pkmn)
# #ret = self.back_sprite_bitmap(species, pkmn.shiny?, pkmn.bodyShiny?, pkmn.headShiny?)
# else
# ret = front_sprite_bitmap(pkmn)
# #ret = self.front_sprite_bitmap(species, pkmn.shiny?, pkmn.bodyShiny?, pkmn.headShiny?)
# end
ret.scale_bitmap(pkmn.sprite_scale) if ret # 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)
ret = self.back_sprite_bitmap(id, shiny, bodyShiny, headShiny)
else
ret = self.front_sprite_bitmap(id, shiny, bodyShiny, headShiny)
ret = self.front_sprite_bitmap(id, shiny, bodyShiny, headShiny)
end
return ret
end
@@ -47,13 +49,12 @@ module GameData
elsif isBodyShiny && SHINY_COLOR_OFFSETS[body_number]&.dig(color)
offset = SHINY_COLOR_OFFSETS[body_number]&.dig(color)
else
return 0 if color != :v1
return 0 if color != :c1
offset = calculateShinyHueOffsetDefaultMethod(body_number, head_number, dex_number, isBodyShiny, isHeadShiny)
end
return offset
end
def self.hex_to_rgb(hex)
hex = hex.delete("#")
r = hex[0..1].to_i(16)
@@ -64,8 +65,8 @@ module GameData
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)
# 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
@@ -78,16 +79,15 @@ module GameData
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
offset += pbGet(VAR_SHINY_HUE_OFFSET) # for testing - always 0 during normal gameplay
return offset
end
def self.getAutogenSprite(head_id, body_id)
def self.getAutogenSprite(head_id, body_id) end
end
# species can be either a number, a Species objet of a symbol
# species can be either a number, a Species objet of a symbol
# Legacy version - Used when $PokemonSystem.random_sprites is off
# Ignores pokemon.pif_sprites and uses whatever is defined as main
def self.front_sprite_bitmap(species, isShiny = false, bodyShiny = false, headShiny = false)
dex_number = getDexNumberForSpecies(species)
if species.is_a?(Species)
@@ -98,7 +98,7 @@ module GameData
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)
sprite = spriteLoader.load_fusion_sprite(head_id, body_id)
else
if isTripleFusion?(dex_number)
sprite = spriteLoader.load_triple_fusion_sprite(dex_number)
@@ -112,10 +112,54 @@ module GameData
return sprite
end
def self.front_sprite_bitmap_pokemon(pokemon)
unless $PokemonSystem.random_sprites
return self.front_sprite_bitmap(pokemon.species, pokemon.shiny?, pokemon.bodyShiny?, pokemon.headShiny?)
end
# todo: integrate triples to pif_sprite system - handled separately for now
if pokemon.isTripleFusion?
spriteloader = BattleSpriteLoader.new
dex_number = getDexNumberForSpecies(pokemon.id_number)
sprite = spriteloader.load_triple_fusion_sprite(dex_number)
if pokemon.shiny?
sprite.shiftAllColors(dex_number, pokemon.body_shiny, pokemon.head_shiny)
end
return sprite
end
##todo
spriteLoader = BattleSpriteLoader.new
unless pokemon.pif_sprite
pif_sprite = front_pif_sprite(pokemon.species, pokemon.shiny?, pokemon.body_shiny, pokemon.head_shiny)
pokemon.pif_sprite = pif_sprite
end
bitmap_sprite = spriteLoader.load_pif_sprite_directly(pokemon.pif_sprite)
if pokemon.shiny?
bitmap_sprite.shiftAllColors(pokemon.id_number, pokemon.body_shiny, pokemon.head_shiny)
end
return bitmap_sprite
end
def self.front_pif_sprite(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)
pif_sprite = spriteLoader.obtain_fusion_pif_sprite(head_id, body_id)
else
if isTripleFusion?(dex_number)
raise "Triple fusions are not implemented for PIF Sprites"
else
pif_sprite = spriteLoader.select_new_pif_base_sprite(dex_number)
end
end
return pif_sprite
end
# def self.front_sprite_bitmap(dex_number, isShiny = false, bodyShiny = false, headShiny = false)
# # body_id = getBodyID(dex_number)
@@ -141,8 +185,8 @@ module GameData
# sprite.shiftColors(self.calculateShinyHueOffset(dex_number, bodyShiny, headShiny))
# end
# return sprite
sprite = self.front_sprite_bitmap(dex_number,isShiny,bodyShiny,headShiny)
return sprite#.mirror
sprite = self.front_sprite_bitmap(dex_number, isShiny, bodyShiny, headShiny)
return sprite #.mirror
end
def self.egg_sprite_bitmap(dex_number, form = nil)
@@ -152,51 +196,49 @@ module GameData
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 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 = "{1}", dex_number
#
# if alt_sprites_substitutions_available && $PokemonGlobal.alt_sprite_substitutions.keys.include?(substitution_id)
# substitutionPath = $PokemonGlobal.alt_sprite_substitutions[substitution_id]
# if alt_sprites_substitutions_available && $PokemonSystem.alt_sprite_substitutions.keys.include?(substitution_id)
# substitutionPath = $PokemonSystem.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
@@ -220,7 +262,7 @@ end
# end
def alt_sprites_substitutions_available
return $PokemonGlobal && $PokemonGlobal.alt_sprite_substitutions
return $PokemonGlobal && $PokemonSystem.alt_sprite_substitutions
end
def print_stack_trace
@@ -232,21 +274,21 @@ 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
# return if !$PokemonSystem.alt_sprite_substitutions
# $PokemonSystem.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
$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
# To force a specific sprites before a battle
#
# ex:
# $PokemonTemp.forced_alt_sprites={"20.25" => "20.25a"}
@@ -255,7 +297,7 @@ class PokemonTemp
attr_accessor :forced_alt_sprites
end
#todo:
# todo:
# DO NOT USE ANYMORE
# Replace by BattleSpriteLoader
# def get_fusion_sprite_path(head_id, body_id, localOnly=false)
@@ -267,8 +309,8 @@ end
# 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]
# if alt_sprites_substitutions_available && $PokemonSystem.alt_sprite_substitutions.keys.include?(substitution_id)
# substitutionPath= $PokemonSystem.alt_sprite_substitutions[substitution_id]
# return substitutionPath if pbResolveBitmap(substitutionPath)
# end
#
@@ -321,28 +363,72 @@ 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?
if $PokemonSystem.random_sprites && $PokemonGlobal
$PokemonSystem.sprites_blacklist = {} unless $PokemonSystem.sprites_blacklist
fusion_species = get_fusion_symbol(head_id, body_id)
species_blacklist = $PokemonSystem.sprites_blacklist[fusion_species]
if species_blacklist
alts_list = list_all_sprites_letters(spriteName)
.reject { |letter| species_blacklist.include?(letter) }
else
alts_list = list_main_sprites_letters(spriteName)
end
return alts_list.sample
else
alts_list = list_all_sprites_letters(spriteName)
return nil if alts_list.empty?
return alts_list.sample
if onlyMain
alts_list = list_main_sprites_letters(spriteName)
else
alts_list = list_all_sprites_letters(spriteName)
end
end
return nil if alts_list.empty?
return alts_list.sample
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)
if $PokemonSystem.random_sprites
species = GameData::Species.get(dex_num)&.species
if $PokemonSystem
$PokemonSystem.sprites_blacklist = {} unless $PokemonSystem.sprites_blacklist
species_blacklist = $PokemonSystem.sprites_blacklist[species]
end
if species_blacklist
letters_list = list_all_sprites_letters(spriteName)
.reject { |letter| species_blacklist.include?(letter) }
else
letters_list = list_main_sprites_letters(spriteName)
end
else
letters_list= list_all_sprites_letters(spriteName)
if onlyMain
letters_list = list_main_sprites_letters(spriteName)
else
letters_list = list_all_sprites_letters(spriteName)
end
letters_list << "" # add main sprite
end
letters_list << "" #add main sprite
return letters_list.sample
end
def get_species_spritename(species_symbol)
species_data = GameData::Species.get(species_symbol)
if species_data.is_fusion
head_number = get_body_number_from_symbol(species_symbol)
body_number = get_body_number_from_symbol(species_symbol)
return "#{head_number}.#{body_number}"
elsif species_data.is_triple_fusion
return "" # todo I guess
else
return "#{species_data.id_number}"
end
end
def list_main_sprites_letters_species(species)
spritename = get_species_spritename(species)
return list_main_sprites_letters(spritename)
end
def list_main_sprites_letters(spriteName)
return list_all_sprites_letters(spriteName) if $PokemonSystem.include_alt_sprites_in_random
all_sprites = map_alt_sprite_letters_for_pokemon(spriteName)
@@ -351,7 +437,7 @@ def list_main_sprites_letters(spriteName)
main_sprites << key if value == "main"
end
#add temp sprites if no main sprites found
# add temp sprites if no main sprites found
if main_sprites.empty?
all_sprites.each do |key, value|
main_sprites << key if value == "temp"
@@ -360,7 +446,7 @@ def list_main_sprites_letters(spriteName)
return main_sprites
end
def list_all_sprites_letters_head_body(head_id,body_id)
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 = []
@@ -387,26 +473,46 @@ def list_alt_sprite_letters(spriteName)
end
end
#ex: "1" -> "main"
# 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
def map_alt_sprite_letters_for_pokemon(spriteName)
alt_sprites = {}
File.foreach(Settings::CREDITS_FILE_PATH) do |line|
row = line.split(',')
row = line.strip.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
next unless sprite_name.start_with?(spriteName)
suffix = sprite_name[spriteName.length..-1] || ""
if suffix.empty?
alt_sprites[""] = row[2]
next
end
# only accept letter-based suffixes: a, b, aa, ab, etc.
next unless suffix.match?(/\A[a-zA-Z]+\z/)
alt_sprites[suffix] = row[2]
end
return alt_sprites
end
alt_sprites
end
@@ -7,7 +7,7 @@ class PIFSprite
attr_accessor :local_path
# types:
# :AUTOGEN, :CUSTOM, :BASE
# :AUTOGEN, :CUSTOM, :BASE, :TRIPLE
def initialize(type, head_id, body_id, alt_letter = "")
@type = type
@head_id = head_id
@@ -34,7 +34,6 @@ class PIFSprite
def exists()
filename = get_spritesheet_path()
echoln filename
return File.file?(filename)
end
@@ -49,7 +48,6 @@ class PIFSprite
else
return nil
end
echoln path
return path
end
end
@@ -63,15 +61,19 @@ def equals(other_pif_sprite)
end
# little hack for old methods that expect a filename for a sprite
def to_filename()
def to_filename(with_extension = true)
case @type
when :CUSTOM
return "#{@head_id}.#{@body_id}#{@alt_letter}.png"
filename= "#{@head_id}.#{@body_id}#{@alt_letter}"
when :AUTOGEN
return "#{@head_id}.#{@body_id}.png"
filename = "#{@head_id}.#{@body_id}"
when :BASE
return "#{@head_id}#{@alt_letter}.png"
filename = "#{@head_id}#{@alt_letter}"
when :TRIPLE
filename = BattleSpriteLoader.new.getSpecialSpriteName(@head_id)
end
filename += ".png" if with_extension
return filename
end
def setup_from_spritename(spritename, type)
@@ -8,15 +8,13 @@ end
def setSpriteSubstitution(head,body)
end
def set_updated_spritesheets
echoln
end
def initialize_alt_sprite_substitutions()
$PokemonGlobal.alt_sprite_substitutions = {} if !$PokemonGlobal.alt_sprite_substitutions
$PokemonSystem.alt_sprite_substitutions = {} if !$PokemonSystem.alt_sprite_substitutions
migrate_sprites_substitutions()
end
@@ -39,8 +37,8 @@ def migrate_sprites_substitutions
return if $game_switches[SWITCH_UPDATED_TO_SPRITESHEETS_SPRITES]
new_substitutions = {}
old_number_pokemon = 470
for dex_number_key in $PokemonGlobal.alt_sprite_substitutions.keys
if $PokemonGlobal.alt_sprite_substitutions[dex_number_key].is_a?(String) && can_convert_to_int?(dex_number_key)
for dex_number_key in $PokemonSystem.alt_sprite_substitutions.keys
if $PokemonSystem.alt_sprite_substitutions[dex_number_key].is_a?(String) && can_convert_to_int?(dex_number_key)
old_dex_number = dex_number_key.to_i
if old_dex_number > old_number_pokemon #fusion
body_id = getBodyID(old_dex_number,old_number_pokemon)
@@ -53,14 +51,14 @@ def migrate_sprites_substitutions
body_id= nil
type = :BASE
end
file_path = $PokemonGlobal.alt_sprite_substitutions[dex_number_key]
file_path = $PokemonSystem.alt_sprite_substitutions[dex_number_key]
alt_letter =get_alt_letter_from_path(file_path)
pif_sprite = PIFSprite.new(type,head_id,body_id,alt_letter)
new_substitutions[new_id] = pif_sprite
end
end
$PokemonGlobal.alt_sprite_substitutions = new_substitutions
$PokemonSystem.alt_sprite_substitutions = new_substitutions
$game_switches[SWITCH_UPDATED_TO_SPRITESHEETS_SPRITES] = true
end