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
@@ -0,0 +1,352 @@
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/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
def initialize(species_left, species_right)
@species_left = species_left
@species_right = species_right
@typewindows = []
@picture1 = nil
@picture2 = nil
@draw_types = nil
@draw_level = nil
@draw_sprite_info = nil
@selected = 0
@last_post=0
@sprites = {}
@sprite_right = nil
@selected_sprite = nil
initializeBackground
initializeSelectArrow
initializeCancelButton
initializeEvolutionsButton
hideAllEvoIcons
end
def getBackgroundPicture
return BACKGROUND_PATH
end
def getSelection
selected = startSelection
@sprites["cancel"].visible=false
#@sprites["arrow"].visible=false
#todo: il y a un fuck en quelque part.... en attendant ca marche inversé ici
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
Input.update
updateSelection
if Input.trigger?(Input::USE)
return @selected
end
if Input.trigger?(Input::BACK)
return -1
end
end
end
def updateSelection
currentSelected = @selected
updateSelectionIndex
if @selected != currentSelected
updateSelectionGraphics
end
end
def updateSelectionIndex
@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::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
def updateSelectionGraphics
if @selected == 0
@sprites["arrow"].x = SELECT_ARROW_X_LEFT
@sprites["arrow"].y = SELECT_ARROW_Y_SELECT
elsif @selected == 1
@sprites["arrow"].x = SELECT_ARROW_X_RIGHT
@sprites["arrow"].y = SELECT_ARROW_Y_SELECT
else
@sprites["arrow"].x = SELECT_ARROW_X_CANCEL
@sprites["arrow"].y = SELECT_ARROW_Y_CANCEL
end
pbUpdateSpriteHash(@sprites)
end
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)
# picturePath = getPicturePath(head_pokemon, body_pokemon)
# bitmap = AnimatedBitmap.new(picturePath)
spriteLoader = BattleSpriteLoader.new
bitmap = GameData::Species.front_sprite_bitmap(dexNumber)
bitmap.shiftAllColors(dexNumber, bodyShiny, headShiny)
bitmap.scale_bitmap(Settings::FRONTSPRITE_SCALE)
pif_sprite = spriteLoader.obtain_fusion_pif_sprite(head_pokemon,body_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 = 99999
drawFusionInformation(dexNumber, level, x)
if !$Trainer.seen?(dexNumber)
if pif_sprite.local_path()
previewwindow.picture.pbSetColor(170, 200, 250, 200) #blue
elsif hasCustom
previewwindow.picture.pbSetColor(150, 255, 150, 200) #green
else
previewwindow.picture.pbSetColor(255, 255, 255, 200) #white
end
end
return previewwindow
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
drawFusionPreviewText(viewport, "Lv. " + level.to_s, x + 80, 40,) if @draw_level
drawSpriteInfoIcons(getPokemon(fusedDexNum),viewport) if @draw_sprite_info
end
def initializeSelectArrow
@sprites["arrow"] = IconSprite.new(0, 0, @viewport)
@sprites["arrow"].setBitmap(ARROW_GRAPHICS_PATH)
@sprites["arrow"].x = SELECT_ARROW_X_LEFT
@sprites["arrow"].y = SELECT_ARROW_Y_SELECT
@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)
@sprites["cancel"].setBitmap(CANCEL_BUTTON_PATH)
@sprites["cancel"].x = CANCEL_BUTTON_X
@sprites["cancel"].y = CANCEL_BUTTON_Y
@sprites["cancel"].z = 100000
end
def initializeBackground()
@sprites["background"] = IconSprite.new(0, 0, @viewport)
@sprites["background"].setBitmap(getBackgroundPicture)
@sprites["background"].x = 0
@sprites["background"].y = 0
@sprites["background"].z = 99999
end
def drawFusionPreviewText(viewport, text, x, y)
label_base_color = Color.new(248, 248, 248)
label_shadow_color = Color.new(104, 104, 104)
overlay = BitmapSprite.new(Graphics.width, Graphics.height, viewport).bitmap
textpos = [[text, x, y, 0, label_base_color, label_shadow_color]]
pbDrawTextPositions(overlay, textpos)
end
#todo
# Adds the icons indicating if the fusion has alt sprites and if the final evo has a custom sprite
# also add a second icon to indidcate if the final evolution has a custom
def drawSpriteInfoIcons(fusedPokemon, viewport)
#pokedexUtils = PokedexUtils.new
#hasAltSprites = pokedexUtils.pbGetAvailableAlts(fusedPokemon).size>1
#pokedexUtils.getFinalEvolution(fusedPokemon).real_name
#todo
end
def dispose
@picture1.dispose
@picture2.dispose
for typeWindow in @typewindows
typeWindow.dispose
end
pbDisposeSpriteHash(@sprites)
end
def drawPokemonType(pokemon_id, viewport, x_pos = 192, y_pos = 264)
width = 66
viewport.z = 1000001
overlay = BitmapSprite.new(Graphics.width, Graphics.height, viewport).bitmap
pokemon = GameData::Species.get(pokemon_id)
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)
type2rect = Rect.new(0, type2_number * 28, 64, 28)
if pokemon.type1 == pokemon.type2
overlay.blt(x_pos + (width / 2), y_pos, typebitmap.bitmap, type1rect)
else
overlay.blt(x_pos, y_pos, typebitmap.bitmap, type1rect)
overlay.blt(x_pos + width, y_pos, typebitmap.bitmap, type2rect)
end
return viewport
end
end
@@ -0,0 +1,38 @@
# class PokemonFusionScene
# HEAD_SPRITE_STARTING_POS = Graphics.width / 2
#
#
# def pbStartScreen(pokemon_head,pokemon_body,pokemon_fused)
#
# @pokemon_head = pokemon_head
# @pokemon_body = pokemon_body
#
# @pokemon_fused = pokemon_fused
#
# @sprites = {}
# @viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
# @viewport.z = 99999
#
# initialize_background()
# initialize_sprites()
# end
#
# def initialize_background()
# addBackgroundOrColoredPlane(@sprites, "background", "DNAbg",
# Color.new(248, 248, 248), @viewport)
# end
#
# def initialize_sprites()
# pokeHead_number = GameData::Species.get(@pokemon_head.species).id_number
# pokeBody_number = GameData::Species.get(@pokemon_body.species).id_number
#
# @sprites["poke_head"] = PokemonSprite.new(@viewport)
# @sprites["poke_head"].setPokemonBitmapFromId(pokeHead_number, false, @pokemon_head.shiny?)
#
# @sprites["poke_head"].ox = @sprites["rsprite1"].bitmap.width / 2
# @sprites["poke_head"].x = Graphics.width / 2
# @sprites["poke_head"].zoom_x = Settings::FRONTSPRITE_SCALE
#
# end
#
# end
@@ -0,0 +1,128 @@
class FusionSelectOptionsScene < PokemonOption_Scene
attr_accessor :selectedAbility
attr_accessor :selectedNature
attr_accessor :hasNickname
attr_accessor :nickname
def initialize(abilityList,natureList, pokemon1, pokemon2)
@abilityList = abilityList
@natureList = natureList
@selectedAbility=nil
@selectedNature=nil
@selBaseColor = Color.new(48,96,216)
@selShadowColor = Color.new(32,32,32)
@show_frame=false
@hasNickname = false
@nickname = nil
@pokemon1=pokemon1
@pokemon2=pokemon2
end
def initUIElements
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(
_INTL("Select your Pokémon's ability and nature"), 0, 0, Graphics.width, 64, @viewport)
@sprites["textbox"] = pbCreateMessageWindow
@sprites["textbox"].letterbyletter = false
pbSetSystemFont(@sprites["textbox"].contents)
@sprites["title"].opacity=0
end
def pbStartScene(inloadscreen = nil)
super
@sprites["option"].opacity=0
end
def getAbilityName(ability)
return GameData::Ability.get(ability.id).name
end
def getAbilityDescription(ability)
return GameData::Ability.get(ability.id).description
end
def getNatureName(nature)
return GameData::Nature.get(nature.id).name
end
def getNatureDescription(nature)
change= GameData::Nature.get(nature.id).stat_changes
return _INTL("Neutral nature") if change.empty?
positiveChange = change[0]
negativeChange = change[1]
return _INTL("+ {1}\n- {2}",GameData::Stat.get(positiveChange[0]).name,GameData::Stat.get(negativeChange[0]).name)
end
def shouldSelectNickname
if @pokemon1.nicknamed? && @pokemon2.nicknamed?
@hasNickname=true
return true
end
if @pokemon1.nicknamed? && !@pokemon2.nicknamed?
@hasNickname=true
@nickname = @pokemon1.name
return false
end
if !@pokemon1.nicknamed? && @pokemon2.nicknamed?
@hasNickname=true
@nickname = @pokemon2.name
return false
end
@hasNickname=false
return false
end
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
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])]
)
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
#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
end
end
@@ -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
@@ -0,0 +1,50 @@
class FusionPreviewScreen < DoublePreviewScreen
attr_reader :poke1
attr_reader :poke2
attr_reader :fusedPokemon
attr_reader :fusedPokemon
attr_writer :draw_types
attr_writer :draw_level
BACKGROUND_PATH = "Graphics/Pictures/DNAbg"
def initialize(poke1,poke2, usingSuperSplicers=false)
super(poke1,poke2)
@draw_types = true
@draw_level = true
@draw_sprite_info=true
#@viewport = viewport
@poke1 = poke1
@poke2 = poke2
@fusedPokemon=nil
if poke1.isShiny?
shiny = true
poke1_shiny = true
end
if poke2.isShiny?
shiny = true
poke2_shiny = true
end
new_level = calculateFusedPokemonLevel(poke1.level, poke2.level, usingSuperSplicers)
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,0)
@picture2 = draw_window(fusion_right,new_level,270,30,shiny,poke2_shiny,poke1_shiny,1)
@sprites["picture1"] = @picture1
@sprites["picture2"] = @picture2
end
def getBackgroundPicture
super
end
end