mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-11 07:04:59 +00:00
update 6.7
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
def spriteOptionsMenu
|
||||
commands = []
|
||||
cmd_manual_update= _INTL("Update sprites manually")
|
||||
cmd_clear_sprite_cache = _INTL("Clear sprite cache")
|
||||
cmd_reset_alt_sprites = _INTL("Reset selected sprites")
|
||||
cmd_cancel = _INTL("Cancel")
|
||||
commands << cmd_manual_update
|
||||
commands << cmd_clear_sprite_cache
|
||||
commands << cmd_reset_alt_sprites
|
||||
commands << cmd_cancel
|
||||
|
||||
chosen = optionsMenu(commands)
|
||||
|
||||
case commands[chosen]
|
||||
when cmd_manual_update
|
||||
should_update = pbConfirmMessage(_INTL("Would you like to redownload the spritepack's data to make sure that all sprites are correctly updated?"))
|
||||
update_spritepack_files if should_update
|
||||
when cmd_reset_alt_sprites
|
||||
confirmed = pbConfirmMessage(_INTL("Reset the chosen alternate sprites set for every Pokémon?"))
|
||||
if confirmed
|
||||
$PokemonGlobal.alt_sprite_substitutions=Hash.new
|
||||
pbMessage(_INTL("Alt sprites substitutions have been reset."))
|
||||
end
|
||||
when cmd_clear_sprite_cache
|
||||
confirmed = pbConfirmMessage(_INTL("Clear the temporary sprites cache for every Pokémon? Every sprite will be fully reloaded the next time they are shown."))
|
||||
if confirmed
|
||||
spritesLoader = BattleSpriteLoader.new
|
||||
spritesLoader.clear_sprites_cache(:CUSTOM)
|
||||
spritesLoader.clear_sprites_cache(:BASE)
|
||||
pbMessage(_INTL("The sprites cache was cleared."))
|
||||
end
|
||||
end
|
||||
end
|
||||
1028
Data/Scripts/052_InfiniteFusion/Menus/BetterRegionMap.rb
Normal file
1028
Data/Scripts/052_InfiniteFusion/Menus/BetterRegionMap.rb
Normal file
File diff suppressed because it is too large
Load Diff
72
Data/Scripts/052_InfiniteFusion/Menus/ExperimentalOptions.rb
Normal file
72
Data/Scripts/052_InfiniteFusion/Menus/ExperimentalOptions.rb
Normal file
@@ -0,0 +1,72 @@
|
||||
|
||||
module OptionTypes
|
||||
WILD_POKE = 0
|
||||
TRAINER_POKE = 1
|
||||
end
|
||||
|
||||
class ExperimentalOptionsScene < PokemonOption_Scene
|
||||
def initialize
|
||||
super
|
||||
@openTrainerOptions = false
|
||||
@openWildOptions = false
|
||||
@openGymOptions = false
|
||||
@openItemOptions = false
|
||||
$game_switches[SWITCH_RANDOMIZED_AT_LEAST_ONCE] = true
|
||||
end
|
||||
|
||||
def getDefaultDescription
|
||||
return _INTL("Set the randomizer settings")
|
||||
end
|
||||
|
||||
def pbStartScene(inloadscreen = false)
|
||||
super
|
||||
@changedColor = true
|
||||
@sprites["title"] = Window_UnformattedTextPokemon.newWithSize(
|
||||
_INTL("Experimental options"), 0, 0, Graphics.width, 64, @viewport)
|
||||
@sprites["textbox"].text = getDefaultDescription
|
||||
pbFadeInAndShow(@sprites) { pbUpdate }
|
||||
end
|
||||
|
||||
def pbGetOptions(inloadscreen = false)
|
||||
options = [
|
||||
EnumOption.new(_INTL("Expert mode (beta)"), [_INTL("On"), _INTL("Off")],
|
||||
proc {
|
||||
$game_switches[SWITCH_EXPERT_MODE] ? 0 : 1
|
||||
},
|
||||
proc { |value|
|
||||
$game_switches[SWITCH_EXPERT_MODE] = value == 0
|
||||
}, _INTL("Changes all of the trainer teams to make them as challenging as possible!")
|
||||
),
|
||||
EnumOption.new(_INTL("No levels mode"), [_INTL("On"), _INTL("Off")],
|
||||
proc {
|
||||
$game_switches[SWITCH_NO_LEVELS_MODE] ? 0 : 1
|
||||
},
|
||||
proc { |value|
|
||||
$game_switches[SWITCH_NO_LEVELS_MODE] = value == 0
|
||||
}, _INTL("All Pokémon use their base stats, regardless of levels.")
|
||||
),
|
||||
EnumOption.new(_INTL("Reversed mode"), [_INTL("On"), _INTL("Off")],
|
||||
proc {
|
||||
$game_switches[SWITCH_REVERSED_MODE] ? 0 : 1
|
||||
},
|
||||
proc { |value|
|
||||
$game_switches[SWITCH_REVERSED_MODE] = value == 0
|
||||
}, _INTL("Inverts the fusions of all the trainers in the game.")
|
||||
)
|
||||
|
||||
#,
|
||||
# EnumOption.new("Double abilities", ["On", "Off"],
|
||||
# proc {
|
||||
# $game_switches[SWITCH_DOUBLE_ABILITIES] ? 0 : 1
|
||||
# },
|
||||
# proc { |value|
|
||||
# $game_switches[SWITCH_DOUBLE_ABILITIES] = value == 0
|
||||
# }, "Fused Pokémon have two abilities at the same time"
|
||||
#)
|
||||
|
||||
]
|
||||
return options
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
59
Data/Scripts/052_InfiniteFusion/Menus/GameModeMenu.rb
Normal file
59
Data/Scripts/052_InfiniteFusion/Menus/GameModeMenu.rb
Normal file
@@ -0,0 +1,59 @@
|
||||
def select_game_mode
|
||||
game_mode = nil
|
||||
|
||||
cmd_mode_classic = _INTL("Classic")
|
||||
cmd_mode_remix = _INTL("Remix Mode")
|
||||
cmd_mode_random = _INTL("Randomized Mode")
|
||||
cmd_mode_legendary = _INTL("Legendary Mode")
|
||||
cmd_mode_expert = _INTL("Expert Mode") #Disabled - Moved to experimental options
|
||||
|
||||
commands = []
|
||||
commands << cmd_mode_classic
|
||||
commands << cmd_mode_remix
|
||||
commands << cmd_mode_random
|
||||
commands << cmd_mode_legendary if $Trainer.new_game_plus_unlocked
|
||||
echoln $Trainer.new_game_plus_unlocked
|
||||
commands_choose_mode = []
|
||||
|
||||
until game_mode
|
||||
chosen_index = pbMessage(_INTL("Which mode would you like to play?"),commands)
|
||||
case commands[chosen_index]
|
||||
when cmd_mode_classic
|
||||
commands_choose_mode = [_INTL("Back"),_INTL("Play Classic Mode")]
|
||||
confirmed_index = pbMessage(_INTL("\\C[1]Classic\\C[0] is the default game mode. All of the player teams and encounters are based on the original games. Every Pokémon is still available."),commands_choose_mode)
|
||||
game_mode = :CLASSIC if confirmed_index ==1
|
||||
when cmd_mode_remix
|
||||
commands_choose_mode = [_INTL("Back"),_INTL("Play Remix Mode")]
|
||||
confirmed_index = pbMessage(_INTL("\\C[1]Remix mode\\C[0] is a special mode made by some members of the community that changes all of the trainer teams and wild encounters to showcase more Pokémon from the newer generations."),commands_choose_mode)
|
||||
game_mode = :REMIX if confirmed_index ==1
|
||||
when cmd_mode_random
|
||||
commands_choose_mode = [_INTL("Back"),_INTL("Play Randomized Mode")]
|
||||
confirmed_index = pbMessage(_INTL("In \\C[1]Randomized mode\\C[0] all of the trainers, wild encounters and items can be randomized. You'll get to customize exactly how you want everything to be randomized."),commands_choose_mode)
|
||||
game_mode = :RANDOMIZED if confirmed_index ==1
|
||||
when cmd_mode_legendary
|
||||
commands_choose_mode = [_INTL("Back"),_INTL("Play Legendary Mode")]
|
||||
confirmed_index = pbMessage(_INTL("In \\C[1]Legendary mode\\C[0], every trainer Pokémon gets fused with a legendary Pokémon. You also start with an egg of every legendary Pokémon in your PC and get a legendary starter."),commands_choose_mode)
|
||||
game_mode = :LEGENDARY if confirmed_index ==1
|
||||
when cmd_mode_expert
|
||||
commands_choose_mode = [_INTL("Back"),_INTL("Play Expert Mode")]
|
||||
confirmed_index = pbMessage(_INTL("\\C[1]Expert mode\\C[0] mode is similar to Classic mode, but it changes all of the trainer teams to make them as challenging as possible. This is for veteran Pokémon trainers only!"),commands_choose_mode)
|
||||
game_mode = :EXPERT if confirmed_index ==1
|
||||
end
|
||||
end
|
||||
apply_game_mode(game_mode)
|
||||
return game_mode
|
||||
end
|
||||
|
||||
def apply_game_mode(game_mode)
|
||||
case game_mode
|
||||
when :REMIX
|
||||
$game_switches[SWITCH_MODERN_MODE] = true
|
||||
when :RANDOMIZED
|
||||
$game_switches[SWITCH_RANDOMIZED_MODE_INTRO]=true
|
||||
pbSet(VAR_CURRENT_GYM_TYPE,-1)
|
||||
when :LEGENDARY
|
||||
initializeLegendaryMode
|
||||
when :EXPERT
|
||||
$game_switches[SWITCH_EXPERT_MODE] = true
|
||||
end
|
||||
end
|
||||
495
Data/Scripts/052_InfiniteFusion/Menus/IntroScreen.rb
Normal file
495
Data/Scripts/052_InfiniteFusion/Menus/IntroScreen.rb
Normal file
@@ -0,0 +1,495 @@
|
||||
#===============================================================================
|
||||
# New animated Title Screens for Pokemon Essentials
|
||||
# by Luka S.J.
|
||||
#
|
||||
# Adds new visual styles to the Pokemon Essentials title screen, and animates
|
||||
# depending on the style selected
|
||||
#===============================================================================
|
||||
###SCRIPTEDIT1
|
||||
# Config value for selecting title screen style
|
||||
SCREENSTYLE = 1
|
||||
# 1 - FR/LG
|
||||
# 2 - R/S/E
|
||||
|
||||
class Scene_Intro
|
||||
|
||||
alias main_old main
|
||||
|
||||
def playIntroCinematic
|
||||
intro_frames_path = "Graphics\\Pictures\\Intro\\INTRO-%03d"
|
||||
intro_bgm = "INTRO_music_cries"
|
||||
intro_movie = Movie.new(intro_frames_path,intro_bgm,230,true)
|
||||
intro_movie.playInViewPort(@viewport)
|
||||
end
|
||||
|
||||
def main
|
||||
Graphics.transition(0)
|
||||
# Cycles through the intro pictures
|
||||
@skip = false
|
||||
|
||||
|
||||
playIntroCinematic
|
||||
# Selects title screen style
|
||||
@screen = GenOneStyle.new
|
||||
# Plays the title screen intro (is skippable)
|
||||
@screen.intro
|
||||
# Creates/updates the main title screen loop
|
||||
self.update
|
||||
Graphics.freeze
|
||||
end
|
||||
|
||||
def update
|
||||
ret = 0
|
||||
loop do
|
||||
@screen.update
|
||||
Graphics.update
|
||||
Input.update
|
||||
if continueKeyPressed?
|
||||
ret = 2
|
||||
break
|
||||
end
|
||||
end
|
||||
case ret
|
||||
when 1
|
||||
closeSplashDelete(scene, args)
|
||||
when 2
|
||||
closeTitle
|
||||
end
|
||||
end
|
||||
|
||||
def closeTitle
|
||||
# Play Pokemon cry
|
||||
pbSEPlay("Absorb2", 100, 100)
|
||||
# Fade out
|
||||
pbBGMStop(1.0)
|
||||
# disposes current title screen
|
||||
disposeTitle
|
||||
#clearTempFolder
|
||||
# initializes load screen
|
||||
sscene = PokemonLoad_Scene.new
|
||||
sscreen = PokemonLoadScreen.new(sscene)
|
||||
sscreen.pbStartLoadScreen
|
||||
end
|
||||
|
||||
def closeTitleDelete
|
||||
pbBGMStop(1.0)
|
||||
# disposes current title screen
|
||||
disposeTitle
|
||||
# initializes delete screen
|
||||
sscene = PokemonLoadScene.new
|
||||
sscreen = PokemonLoad.new(sscene)
|
||||
sscreen.pbStartDeleteScreen
|
||||
end
|
||||
|
||||
# def cyclePics(pics)
|
||||
# sprite=Sprite.new
|
||||
# sprite.opacity=0
|
||||
# for i in 0...pics.length
|
||||
# bitmap=pbBitmap("Graphics/Titles/#{pics[i]}")
|
||||
# sprite.bitmap=bitmap
|
||||
# 15.times do
|
||||
# sprite.opacity+=17
|
||||
# pbWait(1)
|
||||
# end
|
||||
# wait(32)
|
||||
# 15.times do
|
||||
# sprite.opacity-=17
|
||||
# pbWait(1)
|
||||
# end
|
||||
# end
|
||||
# sprite.dispose
|
||||
# end
|
||||
|
||||
def disposeTitle
|
||||
@screen.dispose
|
||||
end
|
||||
|
||||
def wait(frames)
|
||||
return if @skip
|
||||
frames.times do
|
||||
Graphics.update
|
||||
Input.update
|
||||
@skip = true if continueKeyPressed?()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def continueKeyPressed?()
|
||||
return Input.trigger?(Input::USE) ||
|
||||
Input.trigger?(Input::ACTION) ||
|
||||
Input.trigger?(Input::BACK) ||
|
||||
Input.trigger?(Input::SPECIAL)
|
||||
end
|
||||
#===============================================================================
|
||||
# Styled to look like the FRLG games
|
||||
#===============================================================================
|
||||
class GenOneStyle
|
||||
|
||||
def initialize
|
||||
#Kernel.pbDisplayText("Keybindings: F1", 80, 0, 99999)
|
||||
#Kernel.pbDisplayText("Version " + Settings::GAME_VERSION_NUMBER, 254, 308, 99999)
|
||||
|
||||
|
||||
@maxPoke = 140 #1st gen, pas de legend la premiere fois, graduellement plus de poke
|
||||
@customPokeList = getCustomSpeciesList(false)
|
||||
#Get random Pokemon (1st gen orandPokenly, pas de legend la prmeiere fois)
|
||||
|
||||
random_fusion = getRandomFusionForIntro()
|
||||
random_fusion_body = random_fusion.body_id
|
||||
random_fusion_head = random_fusion.head_id
|
||||
|
||||
# if randpoke_body && randpoke_head
|
||||
# path_s1 = get_unfused_sprite_path(randpoke_body,true)
|
||||
# path_s2 = get_unfused_sprite_path(randpoke_head,true)
|
||||
# path_f = get_fusion_sprite_path(randpoke_body, randpoke_head,true)
|
||||
|
||||
@prevPoke1 = random_fusion_body
|
||||
@prevPoke2 = random_fusion_head
|
||||
#end
|
||||
@spriteLoader = BattleSpriteLoader.new
|
||||
|
||||
@selector_pos = 0 #1: left, 0:right
|
||||
|
||||
# sound file for playing the title screen BGM
|
||||
bgm = "Pokemon Red-Blue Opening"
|
||||
@skip = false
|
||||
# speed of the effect movement
|
||||
@speed = 16
|
||||
@opacity = 17
|
||||
@disposed = false
|
||||
|
||||
@currentFrame = 0
|
||||
# calculates after how many frames the game will reset
|
||||
#@totalFrames=getPlayTime("Audio/BGM/#{bgm}")*Graphics.frame_rate
|
||||
@totalFrames = 10 * Graphics.frame_rate
|
||||
|
||||
pbBGMPlay(bgm)
|
||||
|
||||
# creates all the necessary graphics
|
||||
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||
@viewport.z = 99998
|
||||
@sprites = {}
|
||||
|
||||
@sprites["bars"] = Sprite.new(@viewport)
|
||||
@sprites["bars"].bitmap = pbBitmap("Graphics/Titles/gen1_bars")
|
||||
@sprites["bars"].x = Graphics.width
|
||||
@sprites["bg"] = Sprite.new(@viewport)
|
||||
@sprites["bg"].bitmap = pbBitmap("Graphics/Titles/gen1_bg")
|
||||
@sprites["bg"].x = -Graphics.width
|
||||
|
||||
@sprites["logo"] = Sprite.new(@viewport)
|
||||
@sprites["logo"].bitmap = pbBitmap("Graphics/Titles/PokemonInfiniteFusionLogo_Main_25")
|
||||
@sprites["logo"].tone = Tone.new(255, 255, 255, 255)
|
||||
@sprites["logo"].x = (Graphics.width/2)-125
|
||||
@sprites["logo"].y = 0
|
||||
|
||||
@sprites["logo"].opacity = 0
|
||||
@sprites["logo"].z = 9999
|
||||
|
||||
@sprites["logo_bg"] = Sprite.new(@viewport)
|
||||
@sprites["logo_bg"].bitmap = pbBitmap("Graphics/Titles/PokemonInfiniteFusionLogo_Back_25")
|
||||
@sprites["logo_bg"].tone = Tone.new(255, 255, 255, 255)
|
||||
@sprites["logo_bg"].x = (Graphics.width/2)-125
|
||||
@sprites["logo_bg"].y = 0
|
||||
|
||||
@sprites["logo_bg"].opacity = 0
|
||||
|
||||
#@sprites["bg2"]=Sprite.new(@viewport)
|
||||
#@sprites["bg2"].bitmap=pbBitmap("Graphics/Titles/gen1_bg_litup")
|
||||
#@sprites["bg2"].opacity=0
|
||||
|
||||
@sprites["start"]=Sprite.new(@viewport)
|
||||
@sprites["start"].bitmap=pbBitmap("Graphics/Titles/intro_pressKey2")
|
||||
@sprites["start"].x=125
|
||||
@sprites["start"].y=350
|
||||
@sprites["start"].opacity=0
|
||||
|
||||
|
||||
@sprites["effect"] = AnimatedPlane.new(@viewport)
|
||||
@sprites["effect"].bitmap = pbBitmap("Graphics/Titles/gen1_effect")
|
||||
@sprites["effect"].opacity = 155
|
||||
@sprites["effect"].visible = false
|
||||
|
||||
@sprites["selector"] = Sprite.new(@viewport)
|
||||
@sprites["selector"].bitmap = pbBitmap("Graphics/Titles/selector")
|
||||
@sprites["selector"].x = 0
|
||||
@sprites["selector"].y = 200
|
||||
@sprites["selector"].opacity = 0
|
||||
|
||||
@sprites["poke"] = Sprite.new(@viewport)
|
||||
@sprites["poke"].bitmap = @spriteLoader.load_base_sprite(random_fusion_body).bitmap
|
||||
@sprites["poke"].x = 400
|
||||
@sprites["poke"].y = 100
|
||||
|
||||
@sprites["2poke"] = Sprite.new(@viewport)
|
||||
@sprites["2poke"].bitmap = @spriteLoader.load_base_sprite(random_fusion_head).bitmap
|
||||
@sprites["2poke"].x = -150
|
||||
@sprites["2poke"].y = 100
|
||||
|
||||
@sprites["fpoke"] = Sprite.new(@viewport)
|
||||
|
||||
fusedPoke = @spriteLoader.load_pif_sprite(random_fusion)
|
||||
if fusedPoke
|
||||
@sprites["fpoke"].bitmap = fusedPoke.bitmap
|
||||
end
|
||||
@sprites["fpoke"].x = 125
|
||||
@sprites["fpoke"].y = 100
|
||||
@sprites["fpoke"].z = 999
|
||||
@sprites["fpoke"].opacity = 0
|
||||
|
||||
@sprites["fpoke"].z = 999
|
||||
|
||||
@sprites["poke"].tone = Tone.new(0, 0, 0, 255)
|
||||
@sprites["poke"].opacity = 0
|
||||
@sprites["poke2"] = Sprite.new(@viewport)
|
||||
# @sprites["poke2"].bitmap = pbBitmap("Graphics/Battlers/21364")
|
||||
@sprites["poke2"].tone = Tone.new(255, 255, 255, 255)
|
||||
@sprites["poke2"].src_rect.set(0, Graphics.height, Graphics.width, 48)
|
||||
@sprites["poke2"].y = Graphics.height
|
||||
@sprites["poke2"].y = 125
|
||||
@sprites["poke2"].z = 999
|
||||
|
||||
@sprites["2poke"].tone = Tone.new(0, 0, 0, 255)
|
||||
@sprites["2poke"].opacity = 0
|
||||
@sprites["2poke2"] = Sprite.new(@viewport)
|
||||
@sprites["2poke2"].bitmap = pbBitmap("Graphics/Battlers/special/000")
|
||||
@sprites["2poke2"].tone = Tone.new(255, 255, 255, 255)
|
||||
@sprites["2poke2"].src_rect.set(0, Graphics.height, Graphics.width, 48)
|
||||
@sprites["2poke2"].y = Graphics.height
|
||||
@sprites["2poke2"].y = 125
|
||||
@sprites["2poke2"].z = 999
|
||||
|
||||
@sprites["star"] = Sprite.new(@viewport)
|
||||
@sprites["star"].bitmap = pbBitmap("Graphics/Pictures/darkness")
|
||||
@sprites["star"].opacity = 0
|
||||
@sprites["star"].x = -50
|
||||
@sprites["star"].y = 0
|
||||
|
||||
end
|
||||
|
||||
def intro
|
||||
wait(16)
|
||||
16.times do
|
||||
end
|
||||
wait(32)
|
||||
64.times do
|
||||
|
||||
@sprites["2poke"].opacity += 4
|
||||
@sprites["poke"].opacity += 4
|
||||
wait(1)
|
||||
end
|
||||
8.times do
|
||||
@sprites["bg"].x += 64
|
||||
wait(1)
|
||||
end
|
||||
wait(8)
|
||||
8.times do
|
||||
@sprites["bars"].x -= 64
|
||||
wait(1)
|
||||
end
|
||||
wait(8)
|
||||
showUIElements()
|
||||
|
||||
|
||||
|
||||
@sprites["poke"].tone = Tone.new(0, 0, 0, 0)
|
||||
@sprites["2poke"].tone = Tone.new(0, 0, 0, 0)
|
||||
|
||||
@sprites["effect"].visible = false
|
||||
c = 255.0
|
||||
16.times do
|
||||
@sprites["poke2"].opacity -= 255.0 / 16
|
||||
@sprites["2poke2"].opacity -= 255.0 / 16
|
||||
|
||||
c -= 255.0 / 16
|
||||
@sprites["logo"].tone = Tone.new(c, c, c)
|
||||
@sprites["logo_bg"].tone = Tone.new(c, c, c)
|
||||
@sprites["effect"].ox += @speed
|
||||
|
||||
wait(1)
|
||||
end
|
||||
end
|
||||
|
||||
def showUIElements()
|
||||
@sprites["logo"].opacity = 255
|
||||
@sprites["logo_bg"].opacity = 255
|
||||
@sprites["poke2"].opacity = 255
|
||||
@sprites["2poke2"].opacity = 255
|
||||
@sprites["start"].opacity = 200
|
||||
|
||||
Kernel.pbDisplayText("v." + Settings::GAME_VERSION_NUMBER, 455, 5, 99999,pbColor(:WHITE),pbColor(:INVISIBLE))
|
||||
end
|
||||
|
||||
|
||||
TONE_INCR = 15
|
||||
|
||||
def makeShineEffect()
|
||||
newColor = @sprites["poke"].tone.red + TONE_INCR
|
||||
newTone = Tone.new(newColor, newColor, newColor, 0)
|
||||
@sprites["poke"].tone = newTone
|
||||
@sprites["2poke"].tone = newTone
|
||||
end
|
||||
|
||||
def introloop
|
||||
@sprites["star"].opacity = 0
|
||||
@sprites["poke"].opacity = 255
|
||||
@sprites["2poke"].opacity = 255
|
||||
@sprites["fpoke"].opacity = 0
|
||||
@sprites["poke"].x = @sprites["poke"].x - 1
|
||||
@sprites["2poke"].x = @sprites["2poke"].x + 1
|
||||
|
||||
end
|
||||
|
||||
def update_selector_position()
|
||||
if Input.press?(Input::RIGHT) || Input.press?(Input::LEFT)
|
||||
if Input.press?(Input::RIGHT)
|
||||
@selector_pos = 0
|
||||
@sprites["selector"].opacity = 100
|
||||
elsif Input.press?(Input::LEFT)
|
||||
@selector_pos = 1
|
||||
@sprites["selector"].opacity = 100
|
||||
end
|
||||
else
|
||||
@sprites["selector"].opacity=0
|
||||
end
|
||||
|
||||
if @selector_pos == 0
|
||||
@sprites["selector"].x = @sprites["poke"].x
|
||||
else
|
||||
@sprites["selector"].x = @sprites["2poke"].x
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@sprites["effect"].ox += @speed
|
||||
@currentFrame += 1
|
||||
@skip = false
|
||||
|
||||
if @sprites["poke"].x < 175 #150
|
||||
makeShineEffect()
|
||||
end
|
||||
#update_selector_position()
|
||||
if @sprites["poke"].x > @sprites["2poke"].x
|
||||
@sprites["poke"].x = @sprites["poke"].x - 1
|
||||
@sprites["2poke"].x = @sprites["2poke"].x + 1
|
||||
#@sprites["effect"].opacity-=1
|
||||
#@sprites["bg"].opacity-=1
|
||||
#@sprites["bg2"].opacity+=3
|
||||
end
|
||||
|
||||
if @sprites["poke"].x <= @sprites["2poke"].x
|
||||
@sprites["poke"].opacity = 0
|
||||
@sprites["2poke"].opacity = 0
|
||||
#16.times do
|
||||
@sprites["fpoke"].opacity = 255
|
||||
@sprites["selector"].opacity = 0
|
||||
#wait(1)
|
||||
#end
|
||||
@sprites["poke"].x = 400
|
||||
@sprites["poke"].tone = Tone.new(0, 0, 0, 0)
|
||||
|
||||
@sprites["2poke"].x = -150
|
||||
@sprites["2poke"].tone = Tone.new(0, 0, 0, 0)
|
||||
|
||||
if @maxPoke < NB_POKEMON - 1
|
||||
@maxPoke += 5 #-1 pour que ca arrive pile. tant pis pour kyurem
|
||||
end
|
||||
random_fusion = getRandomFusionForIntro()
|
||||
random_fusion_body = random_fusion.body_id
|
||||
random_fusion_head = random_fusion.head_id
|
||||
|
||||
@prevPoke1 = random_fusion_body
|
||||
@prevPoke2 = random_fusion_head
|
||||
|
||||
@sprites["poke"].bitmap = @spriteLoader.load_base_sprite(random_fusion_body).bitmap
|
||||
@sprites["2poke"].bitmap = @spriteLoader.load_base_sprite(random_fusion_head).bitmap
|
||||
|
||||
wait(150)
|
||||
fusedPoke = @spriteLoader.load_pif_sprite(random_fusion)
|
||||
if fusedPoke
|
||||
@sprites["fpoke"].bitmap = fusedPoke.bitmap
|
||||
end
|
||||
end
|
||||
|
||||
@sprites["fpoke"].opacity -= 10
|
||||
@sprites["effect"].ox += @speed
|
||||
|
||||
|
||||
updatePressStartAnimation(@currentFrame)
|
||||
|
||||
if @currentFrame >= @totalFrames
|
||||
introloop
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
PRESS_START_OPACITY_DIFF=2
|
||||
PRESS_START_ANIMATION_TIME=60
|
||||
def updatePressStartAnimation(currentFrame)
|
||||
return if @sprites["start"].opacity==0
|
||||
@start_opacity_diff=PRESS_START_OPACITY_DIFF if !@start_opacity_diff
|
||||
@sprites["start"].opacity += @start_opacity_diff
|
||||
@sprites["logo_bg"].opacity -= @start_opacity_diff
|
||||
|
||||
if currentFrame % PRESS_START_ANIMATION_TIME == 0
|
||||
if @start_opacity_diff <0
|
||||
@start_opacity_diff = PRESS_START_OPACITY_DIFF
|
||||
else
|
||||
@start_opacity_diff = 0 - PRESS_START_OPACITY_DIFF
|
||||
end
|
||||
end
|
||||
end
|
||||
#new version
|
||||
# def getFusedPath(randpoke1, randpoke2)
|
||||
# # path = rand(2) == 0 ? get_fusion_sprite_path(randpoke_body, randpoke_head,true) : get_fusion_sprite_path(randpoke_head, randpoke_body,true)
|
||||
# path = get_fusion_sprite_path(randpoke2, randpoke1,true)
|
||||
#
|
||||
# #allow download here because intentional
|
||||
# if Input.press?(Input::RIGHT)
|
||||
# path = get_fusion_sprite_path(randpoke2, randpoke1)
|
||||
# elsif Input.press?(Input::LEFT)
|
||||
# path = get_fusion_sprite_path(randpoke1, randpoke2)
|
||||
# end
|
||||
# return path
|
||||
# end
|
||||
|
||||
end
|
||||
|
||||
# def getFusedPatho(randpoke1s, randpoke2s)
|
||||
# path = rand(2) == 0 ? "Graphics/Battlers/" + randpoke1s + "/" + randpoke1s + "." + randpoke2s : "Graphics/Battlers/" + randpoke2s + "/" + randpoke2s + "." + randpoke1s
|
||||
# if Input.press?(Input::RIGHT)
|
||||
# path = "Graphics/Battlers/" + randpoke2s + "/" + randpoke2s + "." + randpoke1s
|
||||
# elsif Input.press?(Input::LEFT)
|
||||
# path = "Graphics/Battlers/" + randpoke1s + "/" + randpoke1s + "." + randpoke2s
|
||||
# end
|
||||
# return path
|
||||
# end
|
||||
|
||||
def dispose
|
||||
Kernel.pbClearText()
|
||||
pbFadeOutAndHide(@sprites)
|
||||
pbDisposeSpriteHash(@sprites)
|
||||
@viewport.dispose
|
||||
@disposed = true
|
||||
end
|
||||
|
||||
def disposed?
|
||||
return @disposed
|
||||
end
|
||||
|
||||
def wait(frames)
|
||||
return if @skip
|
||||
frames.times do
|
||||
@currentFrame += 1
|
||||
updatePressStartAnimation(@currentFrame)
|
||||
@sprites["effect"].ox += @speed
|
||||
Graphics.update
|
||||
Input.update
|
||||
if continueKeyPressed?
|
||||
@skip = true
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
79
Data/Scripts/052_InfiniteFusion/Menus/Movie.rb
Normal file
79
Data/Scripts/052_InfiniteFusion/Menus/Movie.rb
Normal file
@@ -0,0 +1,79 @@
|
||||
class Movie
|
||||
attr_reader :finished
|
||||
|
||||
def initialize(framesPath, bgm, maxFrame = 1000, canStopEarly=false)
|
||||
@currentFrame = 1
|
||||
@initialTime = nil
|
||||
@timeElapsed = nil
|
||||
@maxFrame = maxFrame
|
||||
@framesPath = framesPath
|
||||
@bgm = bgm
|
||||
@canStopEarly = canStopEarly
|
||||
@finished=false
|
||||
end
|
||||
|
||||
def play(imageNumber = 12)
|
||||
@finished=false
|
||||
@currentFrame = 1
|
||||
@initialTime = Time.now
|
||||
@timeElapsed = Time.now
|
||||
|
||||
pbBGMPlay(@bgm)
|
||||
while (@currentFrame <= @maxFrame)# && !(@canStopEarly && Input::ACTION))
|
||||
if Input.trigger?(Input::C)
|
||||
|
||||
end
|
||||
frame = sprintf(@framesPath, @currentFrame)
|
||||
picture = Game_Picture.new(imageNumber)
|
||||
picture.show(frame, 0, 0, 0, 100, 100, 255, 0)
|
||||
pbWait(Graphics.frame_rate / 20)
|
||||
picture.erase
|
||||
@currentFrame += 1
|
||||
end
|
||||
@finished=true
|
||||
pbBGMStop
|
||||
end
|
||||
|
||||
def playInViewPort(viewport)
|
||||
@finished=false
|
||||
@currentFrame = 1
|
||||
@initialTime = Time.now
|
||||
@timeElapsed = Time.now
|
||||
|
||||
pbBGMPlay(@bgm)
|
||||
while (@currentFrame <= @maxFrame)# && !(@canStopEarly && Input::ACTION))
|
||||
break if Input.trigger?(Input::C) && @canStopEarly
|
||||
frame = sprintf(@framesPath, @currentFrame)
|
||||
picture = Sprite.new(viewport)
|
||||
picture.bitmap = pbBitmap(frame)
|
||||
picture.visible=true
|
||||
pbWait(Graphics.frame_rate / 20)
|
||||
picture.dispose
|
||||
@currentFrame += 1
|
||||
end
|
||||
@finished=true
|
||||
pbBGMStop
|
||||
end
|
||||
|
||||
# not really necessary I think
|
||||
# def pbAutoregulador()
|
||||
# hora_inicio = $game_variables[VARIABLE_TIME_INITIAL]
|
||||
# hora_actual = Time.now
|
||||
# diferencia = (hora_actual - hora_inicio) * 20 #20 frames corresponde a 1 seg
|
||||
# #Redondeo
|
||||
# diferencia_entera = diferencia.to_i
|
||||
#
|
||||
# diferencia_entera = diferencia_entera.to_f
|
||||
#
|
||||
# if diferencia - diferencia_entera >= 0.5
|
||||
# diferencia_entera = diferencia_entera + 1
|
||||
# end
|
||||
#
|
||||
# $game_variables[VARIABLE_CURRENT_FRAME] = diferencia_entera.to_int
|
||||
#
|
||||
# $game_variables[VARIABLE_TIME_ELAPSED] = Time.now
|
||||
#
|
||||
# return $game_variables[VARIABLE_CURRENT_FRAME]
|
||||
# end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,190 @@
|
||||
class PokemonBoxArrow < SpriteWrapper
|
||||
attr_accessor :cursormode
|
||||
|
||||
alias _multiSelect_PokemonBoxArrow_initialize initialize
|
||||
|
||||
def initialize(*args)
|
||||
_multiSelect_PokemonBoxArrow_initialize(*args)
|
||||
@cursormode = "default"
|
||||
@handsprite.addBitmap("point1m", "Graphics/Pictures/Storage/cursor_point_1_m")
|
||||
@handsprite.addBitmap("point2m", "Graphics/Pictures/Storage/cursor_point_2_m")
|
||||
@handsprite.addBitmap("grabm", "Graphics/Pictures/Storage/cursor_grab_m")
|
||||
@handsprite.addBitmap("fistm", "Graphics/Pictures/Storage/cursor_fist_m")
|
||||
@multiheldpkmn = []
|
||||
end
|
||||
|
||||
alias _multiSelect_PokemonBoxArrow_dispose dispose
|
||||
|
||||
def dispose
|
||||
_multiSelect_PokemonBoxArrow_dispose
|
||||
@multiheldpkmn.each { |pkmn| pkmn.dispose }
|
||||
end
|
||||
|
||||
alias _multiSelect_PokemonBoxArrow_visible_eq visible=
|
||||
|
||||
def visible=(value)
|
||||
_multiSelect_PokemonBoxArrow_visible_eq(value)
|
||||
multiHeldPokemon.each { |pkmn| pkmn.visible = value }
|
||||
end
|
||||
|
||||
alias _multiSelect_PokemonBoxArrow_color_eq color=
|
||||
|
||||
def color=(value)
|
||||
_multiSelect_PokemonBoxArrow_color_eq(value)
|
||||
multiHeldPokemon.each { |pkmn| pkmn.color = value }
|
||||
end
|
||||
|
||||
alias _multiSelect_PokemonBoxArrow_x_eq x=
|
||||
|
||||
def x=(value)
|
||||
_multiSelect_PokemonBoxArrow_x_eq(value)
|
||||
multiHeldPokemon.each { |pkmn| pkmn.x = self.x + (pkmn.heldox * 48) } if holdingMulti?
|
||||
end
|
||||
|
||||
alias _multiSelect_PokemonBoxArrow_y_eq y=
|
||||
|
||||
def y=(value)
|
||||
_multiSelect_PokemonBoxArrow_y_eq(value)
|
||||
multiHeldPokemon.each { |pkmn| pkmn.y = self.y + 16 + (pkmn.heldoy * 48) } if holdingMulti?
|
||||
end
|
||||
|
||||
def setSprite(sprite)
|
||||
if holdingSingle?
|
||||
@heldpkmn = sprite
|
||||
@heldpkmn.viewport = self.viewport if @heldpkmn
|
||||
@heldpkmn.z = 1 if @heldpkmn
|
||||
@holding = false if !@heldpkmn && @multiheldpkmn.length == 0
|
||||
self.z = 2
|
||||
end
|
||||
end
|
||||
|
||||
def setSprites(sprites)
|
||||
if holdingMulti?
|
||||
@multiheldpkmn = sprites
|
||||
for pkmn in @multiheldpkmn
|
||||
pkmn.viewport = self.viewport
|
||||
pkmn.z = 1
|
||||
end
|
||||
@holding = false if !@heldpkmn && @multiheldpkmn.length == 0
|
||||
self.z = 2
|
||||
end
|
||||
end
|
||||
|
||||
alias _multiSelect_PokemonBoxArrow_deleteSprite deleteSprite
|
||||
|
||||
def deleteSprite
|
||||
_multiSelect_PokemonBoxArrow_deleteSprite
|
||||
@multiheldpkmn.each { |pkmn| pkmn.dispose }
|
||||
@multiheldpkmn = []
|
||||
end
|
||||
|
||||
def grabImmediate(sprite)
|
||||
@grabbingState = 0
|
||||
@holding = true
|
||||
@heldpkmn = sprite
|
||||
@heldpkmn.viewport = self.viewport
|
||||
@heldpkmn.z = 1
|
||||
self.z = 2
|
||||
|
||||
self.x = @spriteX
|
||||
self.y = @spriteY
|
||||
end
|
||||
|
||||
def holdingMulti?
|
||||
return @multiheldpkmn.length > 0 && @holding
|
||||
end
|
||||
|
||||
def heldPokemon
|
||||
@heldpkmn = nil if @heldpkmn && @heldpkmn.disposed?
|
||||
@holding = false if !@heldpkmn && @multiheldpkmn.length == 0
|
||||
return @heldpkmn
|
||||
end
|
||||
|
||||
def getModeSprites
|
||||
case @cursormode
|
||||
when "quickswap"
|
||||
return ["point1q", "point2q", "grabq", "fistq"]
|
||||
when "multiselect"
|
||||
return ["point1m", "point2m", "grabm", "fistm"]
|
||||
else
|
||||
return ["point1", "point2", "grab", "fist"]
|
||||
end
|
||||
end
|
||||
|
||||
def update
|
||||
@updating = true
|
||||
super
|
||||
heldpkmn = heldPokemon
|
||||
heldpkmn.update if heldpkmn
|
||||
multiheldpkmn = multiHeldPokemon
|
||||
multiheldpkmn.each { |pkmn| pkmn.update }
|
||||
modeSprites = getModeSprites
|
||||
@handsprite.update
|
||||
@holding = false if !heldpkmn && multiheldpkmn.length == 0
|
||||
if @grabbingState > 0
|
||||
if @grabbingState <= 4 * Graphics.frame_rate / 20
|
||||
@handsprite.changeBitmap(modeSprites[2]) # grab
|
||||
self.y = @spriteY + 4.0 * @grabbingState * 20 / Graphics.frame_rate
|
||||
@grabbingState += 1
|
||||
elsif @grabbingState <= 8 * Graphics.frame_rate / 20
|
||||
@holding = true
|
||||
@handsprite.changeBitmap(modeSprites[3]) # fist
|
||||
self.y = @spriteY + 4 * (8 * Graphics.frame_rate / 20 - @grabbingState) * 20 / Graphics.frame_rate
|
||||
@grabbingState += 1
|
||||
else
|
||||
@grabbingState = 0
|
||||
end
|
||||
elsif @placingState > 0
|
||||
if @placingState <= 4 * Graphics.frame_rate / 20
|
||||
@handsprite.changeBitmap(modeSprites[3]) # fist
|
||||
self.y = @spriteY + 4.0 * @placingState * 20 / Graphics.frame_rate
|
||||
@placingState += 1
|
||||
elsif @placingState <= 8 * Graphics.frame_rate / 20
|
||||
@holding = false
|
||||
@heldpkmn = nil
|
||||
@multiheldpkmn = []
|
||||
@handsprite.changeBitmap(modeSprites[2]) # grab
|
||||
self.y = @spriteY + 4 * (8 * Graphics.frame_rate / 20 - @placingState) * 20 / Graphics.frame_rate
|
||||
@placingState += 1
|
||||
else
|
||||
@placingState = 0
|
||||
end
|
||||
elsif holdingSingle? || holdingMulti?
|
||||
@handsprite.changeBitmap(modeSprites[3]) # fist
|
||||
else
|
||||
self.x = @spriteX
|
||||
self.y = @spriteY
|
||||
if @frame < Graphics.frame_rate / 2
|
||||
@handsprite.changeBitmap(modeSprites[0]) # point1
|
||||
else
|
||||
@handsprite.changeBitmap(modeSprites[1]) # point2
|
||||
end
|
||||
end
|
||||
@handsprite.changeBitmap(getSplicerIcon) if @fusing
|
||||
|
||||
@frame += 1
|
||||
@frame = 0 if @frame >= Graphics.frame_rate
|
||||
@updating = false
|
||||
end
|
||||
|
||||
def multiHeldPokemon
|
||||
@multiheldpkmn.delete_if { |pkmn| pkmn.disposed? }
|
||||
@holding = false if !@heldpkmn && @multiheldpkmn.length == 0
|
||||
return @multiheldpkmn
|
||||
end
|
||||
|
||||
def holdingSingle?
|
||||
return self.heldPokemon && @holding
|
||||
end
|
||||
|
||||
def grabMulti(sprites)
|
||||
@grabbingState = 1
|
||||
@multiheldpkmn = sprites
|
||||
for pkmn in @multiheldpkmn
|
||||
pkmn.viewport = self.viewport
|
||||
pkmn.z = 1
|
||||
end
|
||||
self.z = 2
|
||||
end
|
||||
|
||||
end
|
||||
@@ -0,0 +1,152 @@
|
||||
# selection_helpers.rb (can be split into separate file)
|
||||
module SelectionConstants
|
||||
BOX_NAME = -1
|
||||
PARTY = -2
|
||||
CLOSE = -3
|
||||
PREV_BOX = -4
|
||||
NEXT_BOX = -5
|
||||
end
|
||||
|
||||
module SelectionHelper
|
||||
# Compute visual selection rectangle. Returns a Rect or nil.
|
||||
def self.compute_rect(scene, screen, box, selected)
|
||||
return nil unless screen.multiSelectRange
|
||||
|
||||
displayRect = Rect.new(0, 0, 1, 1)
|
||||
if box == SelectionConstants::BOX_NAME
|
||||
xvalues = []
|
||||
yvalues = []
|
||||
for i in 0...Settings::MAX_PARTY_SIZE
|
||||
xvalues << scene.sprites["boxparty"].x + 18 + 72 * (i % 2)
|
||||
yvalues << scene.sprites["boxparty"].y + 2 + 16 * (i % 2) + 64 * (i / 2)
|
||||
end
|
||||
indexes = screen.getMultiSelection(box, selected)
|
||||
# defensive: if indexes empty, return nil
|
||||
return nil if indexes.nil? || indexes.empty?
|
||||
minx = xvalues[indexes[0]]
|
||||
miny = yvalues[indexes[0]] + 16
|
||||
maxx = xvalues[indexes[indexes.length - 1]] + 72 - 8
|
||||
maxy = yvalues[indexes[indexes.length - 1]] + 64
|
||||
displayRect.set(minx, miny, maxx - minx, maxy - miny)
|
||||
else
|
||||
indexRect = screen.getSelectionRect(box, selected)
|
||||
return nil if indexRect.nil?
|
||||
displayRect.x = scene.sprites["box"].x + 10 + (48 * indexRect.x)
|
||||
displayRect.y = scene.sprites["box"].y + 30 + (48 * indexRect.y) + 16
|
||||
displayRect.width = indexRect.width * 48 + 16
|
||||
displayRect.height = indexRect.height * 48
|
||||
end
|
||||
displayRect
|
||||
end
|
||||
end
|
||||
|
||||
module SelectionNavigator
|
||||
include SelectionConstants
|
||||
|
||||
# Navigate general box grid (supports wrap & special indices)
|
||||
def self.navigate_box(key, selection, screen)
|
||||
case key
|
||||
when Input::UP
|
||||
if screen.multiSelectRange
|
||||
selection -= PokemonBox::BOX_WIDTH
|
||||
selection += PokemonBox::BOX_SIZE if selection < 0
|
||||
elsif selection == BOX_NAME
|
||||
selection = PARTY
|
||||
elsif selection == PARTY
|
||||
selection = PokemonBox::BOX_SIZE - 1 - PokemonBox::BOX_WIDTH * 2 / 3
|
||||
elsif selection == CLOSE
|
||||
selection = PokemonBox::BOX_SIZE - PokemonBox::BOX_WIDTH / 3
|
||||
else
|
||||
selection -= PokemonBox::BOX_WIDTH
|
||||
selection = BOX_NAME if selection < 0
|
||||
end
|
||||
when Input::DOWN
|
||||
if screen.multiSelectRange
|
||||
selection += PokemonBox::BOX_WIDTH
|
||||
selection -= PokemonBox::BOX_SIZE if selection >= PokemonBox::BOX_SIZE
|
||||
elsif selection == BOX_NAME
|
||||
selection = PokemonBox::BOX_WIDTH / 3
|
||||
elsif selection == PARTY
|
||||
selection = BOX_NAME
|
||||
elsif selection == CLOSE
|
||||
selection = BOX_NAME
|
||||
else
|
||||
selection += PokemonBox::BOX_WIDTH
|
||||
if selection >= PokemonBox::BOX_SIZE
|
||||
if selection < PokemonBox::BOX_SIZE + PokemonBox::BOX_WIDTH / 2
|
||||
selection = PARTY
|
||||
else
|
||||
selection = CLOSE
|
||||
end
|
||||
end
|
||||
end
|
||||
when Input::LEFT
|
||||
if screen.multiSelectRange
|
||||
if (selection % PokemonBox::BOX_WIDTH) == 0
|
||||
selection += PokemonBox::BOX_WIDTH - 1
|
||||
else
|
||||
selection -= 1
|
||||
end
|
||||
elsif selection == BOX_NAME
|
||||
selection = PREV_BOX
|
||||
elsif selection == PARTY
|
||||
selection = CLOSE
|
||||
elsif selection == CLOSE
|
||||
selection = PARTY
|
||||
elsif (selection % PokemonBox::BOX_WIDTH) == 0
|
||||
selection += PokemonBox::BOX_WIDTH - 1
|
||||
else
|
||||
selection -= 1
|
||||
end
|
||||
when Input::RIGHT
|
||||
if screen.multiSelectRange
|
||||
if (selection % PokemonBox::BOX_WIDTH) == PokemonBox::BOX_WIDTH - 1
|
||||
selection -= PokemonBox::BOX_WIDTH - 1
|
||||
else
|
||||
selection += 1
|
||||
end
|
||||
elsif selection == BOX_NAME
|
||||
selection = NEXT_BOX
|
||||
elsif selection == PARTY
|
||||
selection = CLOSE
|
||||
elsif selection == CLOSE
|
||||
selection = PARTY
|
||||
elsif (selection % PokemonBox::BOX_WIDTH) == PokemonBox::BOX_WIDTH - 1
|
||||
selection -= PokemonBox::BOX_WIDTH - 1
|
||||
else
|
||||
selection += 1
|
||||
end
|
||||
end
|
||||
selection
|
||||
end
|
||||
|
||||
# Navigate party (left/right/up/down)
|
||||
def self.navigate_party(key, selection, screen)
|
||||
maxIndex = screen.multiSelectRange ? Settings::MAX_PARTY_SIZE - 1 : Settings::MAX_PARTY_SIZE
|
||||
case key
|
||||
when Input::LEFT
|
||||
selection -= 1
|
||||
selection = maxIndex if selection < 0
|
||||
when Input::RIGHT
|
||||
selection += 1
|
||||
selection = 0 if selection > maxIndex
|
||||
when Input::UP
|
||||
if selection == Settings::MAX_PARTY_SIZE
|
||||
selection = Settings::MAX_PARTY_SIZE - 1
|
||||
else
|
||||
selection -= 2
|
||||
selection = selection % Settings::MAX_PARTY_SIZE if screen.multiSelectRange
|
||||
selection = maxIndex if selection < 0
|
||||
end
|
||||
when Input::DOWN
|
||||
if selection == Settings::MAX_PARTY_SIZE
|
||||
selection = 0
|
||||
else
|
||||
selection += 2
|
||||
selection = selection % Settings::MAX_PARTY_SIZE if screen.multiSelectRange
|
||||
selection = maxIndex if selection > maxIndex
|
||||
end
|
||||
end
|
||||
selection
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,12 @@
|
||||
class PokemonBoxIcon < IconSprite
|
||||
attr_accessor :heldox
|
||||
attr_accessor :heldoy
|
||||
|
||||
alias _pokemonBoxIconInitialize initialize
|
||||
|
||||
def initialize(*args)
|
||||
@heldox = 0
|
||||
@heldoy = 0
|
||||
_pokemonBoxIconInitialize(*args)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
class PokemonBoxPartySprite < SpriteWrapper
|
||||
def placePokemonMulti(index, sprites)
|
||||
partyIndex = @pokemonsprites.count { |i| i && i.pokemon && !i.disposed? }
|
||||
for sprite in sprites
|
||||
@pokemonsprites[partyIndex] = sprite
|
||||
partyIndex += 1
|
||||
end
|
||||
if sprites.length > 0
|
||||
@pokemonsprites.compact!
|
||||
refresh
|
||||
end
|
||||
end
|
||||
|
||||
def grabPokemonMulti(indexes, arrowIndex, arrow)
|
||||
grabbedSprites = []
|
||||
arrowX = arrowIndex % 2
|
||||
arrowY = (arrowIndex / 2).floor
|
||||
for index in indexes
|
||||
sprite = @pokemonsprites[index]
|
||||
if sprite && sprite.pokemon && !sprite.disposed?
|
||||
sprite.heldox = (index % 2) - arrowX
|
||||
sprite.heldoy = (index / 2).floor - arrowY
|
||||
grabbedSprites.push(sprite)
|
||||
@pokemonsprites[index] = nil
|
||||
end
|
||||
end
|
||||
if grabbedSprites.length > 0
|
||||
arrow.grabMulti(grabbedSprites)
|
||||
@pokemonsprites.compact!
|
||||
refresh
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,39 @@
|
||||
class PokemonBoxSprite < SpriteWrapper
|
||||
def placePokemonMulti(index, sprites)
|
||||
arrowX = index % PokemonBox::BOX_WIDTH
|
||||
arrowY = (index / PokemonBox::BOX_WIDTH).floor
|
||||
for sprite in sprites
|
||||
spriteIndex = (sprite.heldox + arrowX) + (sprite.heldoy + arrowY) * PokemonBox::BOX_WIDTH
|
||||
@pokemonsprites[spriteIndex] = sprite
|
||||
@pokemonsprites[spriteIndex].refresh
|
||||
end
|
||||
if sprites.length > 0
|
||||
refresh
|
||||
end
|
||||
end
|
||||
|
||||
def grabPokemonMulti(indexes, arrowIndex, arrow)
|
||||
grabbedSprites = []
|
||||
arrowX = arrowIndex % PokemonBox::BOX_WIDTH
|
||||
arrowY = (arrowIndex / PokemonBox::BOX_WIDTH).floor
|
||||
for index in indexes
|
||||
sprite = @pokemonsprites[index]
|
||||
if sprite && sprite.pokemon && !sprite.disposed?
|
||||
sprite.heldox = (index % PokemonBox::BOX_WIDTH) - arrowX
|
||||
sprite.heldoy = (index / PokemonBox::BOX_WIDTH).floor - arrowY
|
||||
grabbedSprites.push(sprite)
|
||||
@pokemonsprites[index] = nil
|
||||
end
|
||||
end
|
||||
if grabbedSprites.length > 0
|
||||
arrow.grabMulti(grabbedSprites)
|
||||
update
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,114 @@
|
||||
class PokemonStorage
|
||||
def pbDeleteMulti(box, indexes)
|
||||
for index in indexes
|
||||
self[box, index] = nil
|
||||
end
|
||||
self.party.compact! if box == -1
|
||||
end
|
||||
|
||||
def pbStoreBatch(pokemon_positions_array, box_index = @currentBox, cursor_x = 0, cursor_y = 0)
|
||||
return -1 if invalid_input?(pokemon_positions_array, box_index)
|
||||
|
||||
box_width = PokemonBox::BOX_WIDTH
|
||||
box_height = PokemonBox::BOX_HEIGHT
|
||||
coords = all_coords(box_width, box_height)
|
||||
|
||||
assignments, unplaced, intended = initialize_assignments(pokemon_positions_array.length)
|
||||
|
||||
spiral = spiral_offsets
|
||||
|
||||
# Phase 1: Lock in guaranteed spots
|
||||
lock_guaranteed_spots(pokemon_positions_array, box_index, cursor_x, cursor_y, box_width, box_height,
|
||||
assignments, unplaced, intended)
|
||||
|
||||
available_coords = filter_available_coords(coords, box_index, box_width, assignments)
|
||||
return :CANT_PLACE if available_coords.length < unplaced.length
|
||||
|
||||
# Phase 2: Assign leftovers using spiral fallback
|
||||
assign_fallback_positions(unplaced, intended, assignments, available_coords, box_width, box_height, cursor_x, cursor_y, spiral)
|
||||
return :CANT_PLACE if assignments.compact.uniq.length < assignments.compact.length
|
||||
|
||||
# Phase 3: Commit placements
|
||||
commit_assignments(assignments, pokemon_positions_array, box_index, box_width)
|
||||
|
||||
unplaced.empty? ? :PLACED_ALL_FREE : :PLACED_OCCUPIED
|
||||
end
|
||||
|
||||
# -----------------------------
|
||||
# Helper methods
|
||||
# -----------------------------
|
||||
def invalid_input?(arr, box_index)
|
||||
arr.nil? || arr.empty? || self[box_index].is_a?(StorageTransferBox)
|
||||
end
|
||||
|
||||
def all_coords(box_width, box_height)
|
||||
(0...box_height).flat_map { |y| (0...box_width).map { |x| [x, y] } }
|
||||
end
|
||||
|
||||
def initialize_assignments(length)
|
||||
[Array.new(length), [], []] # assignments, unplaced, intended
|
||||
end
|
||||
|
||||
def spiral_offsets
|
||||
[[0,0],[1,0],[0,1],[-1,0],[0,-1],[1,1],[-1,1],[1,-1],[-1,-1],[2,0],[0,2],[-2,0],[0,-2]]
|
||||
end
|
||||
|
||||
def lock_guaranteed_spots(pokemon_positions_array, box_index, cursor_x, cursor_y, box_width, box_height, assignments, unplaced, intended)
|
||||
pokemon_positions_array.each_with_index do |pk_data, i|
|
||||
rel_x, rel_y = pk_data[1], pk_data[2]
|
||||
target_x, target_y = cursor_x + rel_x, cursor_y + rel_y
|
||||
intended[i] = [target_x, target_y]
|
||||
|
||||
if target_x.between?(0, box_width-1) && target_y.between?(0, box_height-1)
|
||||
index = target_y * box_width + target_x
|
||||
assignments[i] = [target_x, target_y] if self[box_index, index].nil?
|
||||
unplaced << i if assignments[i].nil?
|
||||
else
|
||||
unplaced << i
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def filter_available_coords(coords, box_index, box_width, assignments)
|
||||
used_coords = assignments.compact
|
||||
coords.reject { |cx, cy| !self[box_index, cy * box_width + cx].nil? || used_coords.include?([cx, cy]) }
|
||||
end
|
||||
|
||||
def assign_fallback_positions(unplaced, intended, assignments, available_coords, box_width, box_height, cursor_x, cursor_y, spiral)
|
||||
unplaced.each_with_index do |i, idx|
|
||||
tx, ty = intended[i] || [cursor_x, cursor_y]
|
||||
chosen = spiral.map { |offx, offy| [tx + offx, ty + offy] }
|
||||
.find { |nx, ny| nx.between?(0, box_width-1) && ny.between?(0, box_height-1) && available_coords.include?([nx, ny]) }
|
||||
chosen ||= available_coords.min_by { |cx, cy| (cx - tx).abs + (cy - ty).abs }
|
||||
raise :CANT_PLACE unless chosen
|
||||
assignments[i] = chosen
|
||||
available_coords.delete(chosen)
|
||||
end
|
||||
end
|
||||
|
||||
def commit_assignments(assignments, pokemon_positions_array, box_index, box_width)
|
||||
assignments.each_with_index do |coords, i|
|
||||
next unless coords
|
||||
cx, cy = coords
|
||||
index = cy * box_width + cx
|
||||
if self[box_index, index].nil?
|
||||
self[box_index, index] = pokemon_positions_array[i][0]
|
||||
else
|
||||
rollback(assignments, pokemon_positions_array, box_index, box_width)
|
||||
raise :CANT_PLACE
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def rollback(assignments, pokemon_positions_array, box_index, box_width)
|
||||
assignments.each do |coords|
|
||||
next unless coords
|
||||
rx, ry = coords
|
||||
rindex = ry * box_width + rx
|
||||
self[box_index, rindex] = nil if pokemon_positions_array.any? { |pk| pk[0] == self[box_index, rindex] }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -0,0 +1,318 @@
|
||||
class PokemonStorageScene
|
||||
include SelectionConstants
|
||||
|
||||
attr_reader :cursormode
|
||||
attr_reader :screen
|
||||
attr_reader :sprites
|
||||
attr_accessor :selection
|
||||
|
||||
alias _storageMultiselect_pbStartBox pbStartBox
|
||||
|
||||
def pbStartBox(*args)
|
||||
_storageMultiselect_pbStartBox(*args)
|
||||
@cursormode = "default"
|
||||
# create a single selection rect sprite used when needed
|
||||
@sprites["selectionrect"] = BitmapSprite.new(Graphics.width, Graphics.height, @arrowviewport)
|
||||
@sprites["selectionrect"].visible = false
|
||||
end
|
||||
|
||||
def pbChangeSelection(key, selection)
|
||||
if @choseFromParty
|
||||
return SelectionNavigator.navigate_party(key, selection, @screen)
|
||||
else
|
||||
return SelectionNavigator.navigate_box(key, selection, @screen)
|
||||
end
|
||||
end
|
||||
|
||||
def pbPartyChangeSelection(key, selection)
|
||||
SelectionNavigator.navigate_party(key, selection, @screen)
|
||||
end
|
||||
|
||||
def pbSelectPartyInternal(party, depositing)
|
||||
selection = @selection
|
||||
pbPartySetArrow(@sprites["arrow"], selection)
|
||||
pbUpdateOverlay(selection, party)
|
||||
pbSetMosaic(selection)
|
||||
lastsel = 1
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
key = -1
|
||||
key = Input::DOWN if Input.repeat?(Input::DOWN)
|
||||
key = Input::RIGHT if Input.repeat?(Input::RIGHT)
|
||||
key = Input::LEFT if Input.repeat?(Input::LEFT)
|
||||
key = Input::UP if Input.repeat?(Input::UP)
|
||||
if key >= 0
|
||||
pbPlayCursorSE
|
||||
newselection = pbPartyChangeSelection(key, selection)
|
||||
if newselection == -1
|
||||
return -1 if !depositing
|
||||
elsif newselection == -2
|
||||
selection = lastsel
|
||||
else
|
||||
selection = newselection
|
||||
end
|
||||
pbPartySetArrow(@sprites["arrow"], selection)
|
||||
lastsel = selection if selection > 0
|
||||
pbUpdateOverlay(selection, party)
|
||||
pbSetMosaic(selection)
|
||||
if @screen.multiSelectRange
|
||||
pbUpdateSelectionRect(-1, selection)
|
||||
end
|
||||
end
|
||||
self.update
|
||||
if Input.trigger?(Input::ACTION) && @command == 0 # Organize only
|
||||
if !@screen.pbHolding?
|
||||
pbPlayDecisionSE
|
||||
pbNextCursorMode
|
||||
end
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
@selection = selection
|
||||
return -1
|
||||
elsif Input.trigger?(Input::USE)
|
||||
if selection >= 0 && selection < Settings::MAX_PARTY_SIZE
|
||||
@selection = selection
|
||||
return selection
|
||||
elsif selection == Settings::MAX_PARTY_SIZE # Close Box
|
||||
@selection = selection
|
||||
return (depositing) ? -3 : -1
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbSelectBoxInternal(_party)
|
||||
selection = @selection
|
||||
pbSetArrow(@sprites["arrow"], selection)
|
||||
pbUpdateOverlay(selection)
|
||||
pbSetMosaic(selection)
|
||||
loop do
|
||||
Graphics.update
|
||||
Input.update
|
||||
key = -1
|
||||
key = Input::DOWN if Input.repeat?(Input::DOWN)
|
||||
key = Input::RIGHT if Input.repeat?(Input::RIGHT)
|
||||
key = Input::LEFT if Input.repeat?(Input::LEFT)
|
||||
key = Input::UP if Input.repeat?(Input::UP)
|
||||
|
||||
if key >= 0
|
||||
pbPlayCursorSE
|
||||
selection = pbChangeSelection(key, selection)
|
||||
pbSetArrow(@sprites["arrow"], selection)
|
||||
if selection == SelectionConstants::PREV_BOX
|
||||
nextbox = (@storage.currentBox + @storage.maxBoxes - 1) % @storage.maxBoxes
|
||||
pbSwitchBoxToLeft(nextbox)
|
||||
@storage.currentBox = nextbox
|
||||
elsif selection == SelectionConstants::NEXT_BOX
|
||||
nextbox = (@storage.currentBox + 1) % @storage.maxBoxes
|
||||
pbSwitchBoxToRight(nextbox)
|
||||
@storage.currentBox = nextbox
|
||||
end
|
||||
selection = BOX_NAME if selection == SelectionConstants::PREV_BOX || selection == SelectionConstants::NEXT_BOX
|
||||
pbUpdateOverlay(selection)
|
||||
pbSetMosaic(selection)
|
||||
if @screen.multiSelectRange
|
||||
pbUpdateSelectionRect(@storage.currentBox, selection)
|
||||
end
|
||||
end
|
||||
self.update
|
||||
if Input.trigger?(Input::JUMPUP)
|
||||
pbPlayCursorSE
|
||||
nextbox = (@storage.currentBox + @storage.maxBoxes - 1) % @storage.maxBoxes
|
||||
pbSwitchBoxToLeft(nextbox)
|
||||
@storage.currentBox = nextbox
|
||||
pbUpdateOverlay(selection)
|
||||
pbSetMosaic(selection)
|
||||
elsif Input.trigger?(Input::JUMPDOWN)
|
||||
pbPlayCursorSE
|
||||
nextbox = (@storage.currentBox + 1) % @storage.maxBoxes
|
||||
pbSwitchBoxToRight(nextbox)
|
||||
@storage.currentBox = nextbox
|
||||
pbUpdateOverlay(selection)
|
||||
pbSetMosaic(selection)
|
||||
elsif Input.trigger?(Input::SPECIAL) # Jump to box name
|
||||
if selection != BOX_NAME
|
||||
pbPlayCursorSE
|
||||
selection = BOX_NAME
|
||||
pbSetArrow(@sprites["arrow"], selection)
|
||||
pbUpdateOverlay(selection)
|
||||
pbSetMosaic(selection)
|
||||
end
|
||||
elsif Input.trigger?(Input::ACTION) && @command == 0 # Organize only
|
||||
pbPlayDecisionSE
|
||||
pbNextCursorMode
|
||||
elsif Input.trigger?(Input::BACK)
|
||||
@selection = selection
|
||||
return nil
|
||||
elsif Input.trigger?(Input::USE)
|
||||
@selection = selection
|
||||
if selection >= 0
|
||||
return [@storage.currentBox, selection]
|
||||
elsif selection == BOX_NAME
|
||||
return [SelectionConstants::PREV_BOX, BOX_NAME]
|
||||
elsif selection == PARTY
|
||||
return [SelectionConstants::PARTY, BOX_NAME]
|
||||
elsif selection == CLOSE
|
||||
return [SelectionConstants::CLOSE, BOX_NAME]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def restartBox(screen, command, animate = true)
|
||||
pbCloseBox(animate)
|
||||
cursormode = @cursormode
|
||||
selection = @selection
|
||||
pbStartBox(screen, command, animate)
|
||||
pbSetCursorMode(cursormode)
|
||||
@selection = selection
|
||||
end
|
||||
|
||||
def pbNextCursorMode()
|
||||
return if @screen.pbHolding?
|
||||
case @cursormode
|
||||
when "default"
|
||||
pbSetCursorMode("multiselect")
|
||||
when "quickswap" #Disabled
|
||||
pbSetCursorMode("default")
|
||||
when "multiselect"
|
||||
#pbSetCursorMode("quickswap") if !@screen.pbHolding?
|
||||
pbSetCursorMode("default")
|
||||
end
|
||||
end
|
||||
|
||||
def pbSetCursorMode(value)
|
||||
@cursormode = value
|
||||
@sprites["arrow"].cursormode = value
|
||||
if @screen.multiSelectRange
|
||||
@screen.multiSelectRange = nil
|
||||
pbUpdateSelectionRect(@choseFromParty ? -1 : @storage.currentBox, 0)
|
||||
end
|
||||
end
|
||||
|
||||
def pbSetHeldPokemon(pokemon)
|
||||
pokesprite = PokemonBoxIcon.new(pokemon, @arrowviewport)
|
||||
@sprites["arrow"].grabImmediate(pokesprite)
|
||||
end
|
||||
|
||||
# Scene draws the rect by asking SelectionHelper for the rect
|
||||
# in PokemonStorageScene
|
||||
def pbUpdateSelectionRect(box, selected)
|
||||
rect = SelectionHelper.compute_rect(self, @screen, box, selected)
|
||||
if rect.nil?
|
||||
@sprites["selectionrect"].visible = false
|
||||
return
|
||||
end
|
||||
|
||||
bmp = @sprites["selectionrect"].bitmap
|
||||
bmp.clear
|
||||
|
||||
color = Color.new(0, 255, 0, 50) # semi-transparent green
|
||||
radius = 12 # corner roundness in pixels
|
||||
|
||||
draw_rounded_rect(bmp, rect.x, rect.y, rect.width, rect.height, radius, color)
|
||||
@sprites["selectionrect"].visible = true
|
||||
end
|
||||
|
||||
# helper method (add to PokemonStorageScene)
|
||||
def draw_rounded_rect(bmp, x, y, w, h, r, color)
|
||||
# central rectangle
|
||||
bmp.fill_rect(x + r, y, w - 2 * r, h, color)
|
||||
bmp.fill_rect(x, y + r, w, h - 2 * r, color)
|
||||
|
||||
# corner circles
|
||||
(0..r).each do |dy|
|
||||
dx = (r * r - dy * dy) ** 0.5
|
||||
# top-left
|
||||
bmp.fill_rect(x + r - dx, y + r - dy, 2 * dx, 1, color)
|
||||
# top-right
|
||||
bmp.fill_rect(x + w - r - dx, y + r - dy, 2 * dx, 1, color)
|
||||
# bottom-left
|
||||
bmp.fill_rect(x + r - dx, y + h - r + dy - 1, 2 * dx, 1, color)
|
||||
# bottom-right
|
||||
bmp.fill_rect(x + w - r - dx, y + h - r + dy - 1, 2 * dx, 1, color)
|
||||
end
|
||||
end
|
||||
|
||||
# --- Animation methods (Scene-only) ---
|
||||
# The scene only animates; it does not change game state or run rules.
|
||||
def animate_hold_multi(box, selected, selected_index)
|
||||
pbSEPlay("GUI storage pick up")
|
||||
if box == BOX_NAME
|
||||
@sprites["boxparty"].grabPokemonMulti(selected, selected_index, @sprites["arrow"])
|
||||
else
|
||||
@sprites["box"].grabPokemonMulti(selected, selected_index, @sprites["arrow"])
|
||||
end
|
||||
while @sprites["arrow"].grabbing?
|
||||
Graphics.update
|
||||
Input.update
|
||||
self.update
|
||||
end
|
||||
end
|
||||
|
||||
def animate_place_multi(box, index)
|
||||
pbSEPlay("GUI storage put down")
|
||||
heldpokesprites = @sprites["arrow"].multiHeldPokemon
|
||||
@sprites["arrow"].place
|
||||
while @sprites["arrow"].placing?
|
||||
Graphics.update
|
||||
Input.update
|
||||
self.update
|
||||
end
|
||||
if box == BOX_NAME
|
||||
@sprites["boxparty"].placePokemonMulti(index, heldpokesprites)
|
||||
else
|
||||
@sprites["box"].placePokemonMulti(index, heldpokesprites)
|
||||
end
|
||||
@boxForMosaic = @storage.currentBox
|
||||
@selectionForMosaic = index
|
||||
end
|
||||
|
||||
def animate_release_multi(box, selected)
|
||||
release_sprites = []
|
||||
for index in selected
|
||||
sprite = nil
|
||||
if box == BOX_NAME
|
||||
sprite = @sprites["boxparty"].getPokemon(index)
|
||||
else
|
||||
sprite = @sprites["box"].getPokemon(index)
|
||||
end
|
||||
release_sprites << sprite if sprite
|
||||
end
|
||||
if release_sprites.length > 0
|
||||
for sprite in release_sprites
|
||||
sprite.release
|
||||
end
|
||||
while release_sprites[0].releasing?
|
||||
Graphics.update
|
||||
for sprite in release_sprites
|
||||
sprite.update
|
||||
end
|
||||
self.update
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def pbHardRefresh
|
||||
oldPartyY = @sprites["boxparty"].y
|
||||
@sprites["box"].dispose
|
||||
@sprites["box"] = PokemonBoxSprite.new(@storage, @storage.currentBox, @boxviewport)
|
||||
@sprites["boxparty"].dispose
|
||||
@sprites["boxparty"] = PokemonBoxPartySprite.new(@storage.party, @boxsidesviewport)
|
||||
@sprites["boxparty"].y = oldPartyY
|
||||
end
|
||||
|
||||
def pbCloseBox(animate = true)
|
||||
pbFadeOutAndHide(@sprites) if animate
|
||||
pbDisposeSpriteHash(@sprites)
|
||||
@markingbitmap.dispose if @markingbitmap
|
||||
@boxviewport.dispose
|
||||
@boxsidesviewport.dispose
|
||||
@arrowviewport.dispose
|
||||
end
|
||||
|
||||
# Convenience wrapper for external code that expects pbPlaceMulti/pbHoldMulti naming:
|
||||
alias pbPlaceMulti animate_place_multi
|
||||
alias pbHoldMulti animate_hold_multi
|
||||
alias pbReleaseMulti animate_release_multi
|
||||
end
|
||||
@@ -0,0 +1,415 @@
|
||||
class PokemonStorageScreen
|
||||
include SelectionConstants
|
||||
|
||||
attr_accessor :multiheldpkmn
|
||||
attr_accessor :multiSelectRange
|
||||
|
||||
alias _storageMultiSelect_initialize initialize
|
||||
|
||||
def initialize(*args)
|
||||
_storageMultiSelect_initialize(*args)
|
||||
@multiheldpkmn = []
|
||||
@multiSelectRange = nil
|
||||
end
|
||||
|
||||
# Top-level loop: delegates move and release actions to screen-level methods.
|
||||
def pcOrganizeCommand()
|
||||
isTransferBox = @storage[@storage.currentBox].is_a?(StorageTransferBox)
|
||||
loop do
|
||||
selected = @scene.pbSelectBox(@storage.party)
|
||||
if selected == nil
|
||||
if pbHolding?
|
||||
if @fusionMode
|
||||
cancelFusion
|
||||
else
|
||||
pbDisplay(_INTL("You're holding a Pokémon!"))
|
||||
end
|
||||
next
|
||||
end
|
||||
if @multiSelectRange
|
||||
pbPlayCancelSE
|
||||
@multiSelectRange = nil
|
||||
@scene.pbUpdateSelectionRect(0, 0)
|
||||
next
|
||||
end
|
||||
next if pbConfirm(_INTL("Continue Box operations?"))
|
||||
break
|
||||
elsif selected[0] == SelectionConstants::CLOSE
|
||||
if pbHolding?
|
||||
if @multiSelectRange
|
||||
pbPlayCancelSE
|
||||
@multiSelectRange = nil
|
||||
@scene.pbUpdateSelectionRect(0, 0)
|
||||
next
|
||||
else
|
||||
pbDisplay(_INTL("You're holding a Pokémon!"))
|
||||
next
|
||||
end
|
||||
end
|
||||
if pbConfirm(_INTL("Exit from the Box?"))
|
||||
pbSEPlay("PC close")
|
||||
break
|
||||
end
|
||||
next
|
||||
elsif selected[0] == SelectionConstants::PREV_BOX
|
||||
pbBoxCommands
|
||||
else
|
||||
pokemon = @storage[selected[0], selected[1]]
|
||||
heldpoke = pbHeldPokemon
|
||||
next if !heldpoke && !pokemon && @scene.cursormode != "multiselect"
|
||||
if @scene.cursormode == "multiselect"
|
||||
multiSelectAction(selected)
|
||||
elsif @scene.cursormode == "quickswap"
|
||||
quickSwap(selected, pokemon)
|
||||
elsif @fusionMode
|
||||
pbFusionCommands(selected)
|
||||
else
|
||||
echoln "pcOrganizeCommand?"
|
||||
organizeActions(selected, pokemon, heldpoke, isTransferBox)
|
||||
end
|
||||
end
|
||||
end
|
||||
@scene.pbCloseBox
|
||||
end
|
||||
|
||||
def selectAllBox
|
||||
@scene.pbSetCursorMode("multiselect")
|
||||
selected_index = PokemonBox::BOX_SIZE - 1
|
||||
@multiSelectRange = [0, nil]
|
||||
box = @storage.currentBox
|
||||
@scene.pbUpdateSelectionRect(box, selected_index,)
|
||||
@scene.selection = selected_index
|
||||
end
|
||||
|
||||
def pbBoxCommands
|
||||
is_holding_pokemon = pbHolding?
|
||||
if @scene.cursormode == "multiselect"
|
||||
if is_holding_pokemon
|
||||
return dropAllHeldPokemon
|
||||
else
|
||||
return selectAllBox
|
||||
end
|
||||
|
||||
end
|
||||
cmd_jump = _INTL("Jump")
|
||||
cmd_select = _INTL("Select all")
|
||||
cmd_wallpaper = _INTL("Wallpaper")
|
||||
cmd_name = _INTL("Name")
|
||||
cmd_info = _INTL("Info")
|
||||
cmd_cancel = _INTL("Cancel")
|
||||
|
||||
commands = []
|
||||
commands << cmd_jump
|
||||
commands << cmd_select unless is_holding_pokemon
|
||||
commands << cmd_wallpaper
|
||||
commands << cmd_name if !@storage[@storage.currentBox].is_a?(StorageTransferBox)
|
||||
commands << cmd_info if @storage[@storage.currentBox].is_a?(StorageTransferBox)
|
||||
commands << cmd_cancel
|
||||
|
||||
command = pbShowCommands(
|
||||
_INTL("What do you want to do?"), commands)
|
||||
case commands[command]
|
||||
when cmd_jump
|
||||
boxCommandJump
|
||||
when cmd_wallpaper
|
||||
boxCommandSetWallpaper
|
||||
when cmd_name
|
||||
boxCommandName
|
||||
when cmd_info
|
||||
boxCommandTransferInfo
|
||||
when cmd_select
|
||||
selectAllBox
|
||||
end
|
||||
end
|
||||
|
||||
def singlePokemonCommands(selected)
|
||||
#@multiSelectRange = nil
|
||||
#@scene.pbUpdateSelectionRect(selected[0], selected[1])
|
||||
isTransferBox = @storage[@storage.currentBox].is_a?(StorageTransferBox)
|
||||
pokemon = @storage[selected[0], selected[1]]
|
||||
heldpoke = pbHeldPokemon
|
||||
return organizeActions(selected, pokemon, heldpoke, isTransferBox)
|
||||
end
|
||||
|
||||
def multipleSelectedPokemonCommands(selected, pokemonCount)
|
||||
commands = []
|
||||
cmdMove = -1
|
||||
cmdRelease = -1
|
||||
cmdCancel = -1
|
||||
cmdSort = -1
|
||||
|
||||
helptext = _INTL("Selected {1} Pokémon.", pokemonCount)
|
||||
|
||||
commands[cmdMove = commands.length] = _INTL("Move")
|
||||
commands[cmdSort = commands.length] = _INTL("Sort")
|
||||
commands[cmdRelease = commands.length] = _INTL("Release") if $DEBUG
|
||||
commands[cmdCancel = commands.length] = _INTL("Cancel")
|
||||
|
||||
command = pbShowCommands(helptext, commands)
|
||||
|
||||
if command == cmdMove
|
||||
pbHoldMulti(selected[0], selected[1])
|
||||
elsif command == cmdSort
|
||||
pbSortMulti(selected[0])
|
||||
elsif command == cmdRelease
|
||||
pbReleaseMulti(selected[0])
|
||||
end
|
||||
end
|
||||
|
||||
def dropAllHeldPokemon
|
||||
multiSelectAction([@storage.currentBox, 0])
|
||||
end
|
||||
|
||||
# Multi-select flow: validates and delegates animations to scene.
|
||||
def multiSelectAction(selected)
|
||||
return unless @scene.cursormode == "multiselect"
|
||||
if pbMultiHeldPokemon.length > 0
|
||||
# placing multi-held from screen's held list
|
||||
place_result = pbPlaceMulti(selected[0], selected[1])
|
||||
if place_result == :PLACED_OCCUPIED
|
||||
pbSEPlay("GUI party switch")
|
||||
end
|
||||
|
||||
elsif !@multiSelectRange
|
||||
pbPlayDecisionSE
|
||||
@multiSelectRange = [selected[1], nil]
|
||||
@scene.pbUpdateSelectionRect(selected[0], selected[1])
|
||||
return
|
||||
elsif !@multiSelectRange[1]
|
||||
@multiSelectRange[1] = selected[1]
|
||||
pokemonCount = 0
|
||||
noneggCount = 0
|
||||
for index in getMultiSelection(selected[0], nil)
|
||||
pokemonCount += 1 if @storage[selected[0], index]
|
||||
if @storage[selected[0], index]
|
||||
noneggCount += 1 unless @storage[selected[0], index].egg?
|
||||
end
|
||||
end
|
||||
if pokemonCount == 0
|
||||
pbPlayCancelSE
|
||||
@multiSelectRange = nil
|
||||
@scene.pbUpdateSelectionRect(selected[0], selected[1])
|
||||
return
|
||||
elsif pokemonCount == 1 && @storage[selected[0], selected[1]]
|
||||
singlePokemonCommands(selected)
|
||||
else
|
||||
multipleSelectedPokemonCommands(selected, pokemonCount)
|
||||
end
|
||||
@multiSelectRange = nil
|
||||
@scene.pbUpdateSelectionRect(selected[0], selected[1])
|
||||
end
|
||||
end
|
||||
|
||||
# --- Screen-side game-rule methods (validate, commit, then animate) ---
|
||||
# Validate & pick up a selection of multiple Pokémon (logical)
|
||||
def pbHoldMulti(box, selected_index)
|
||||
selected = getMultiSelection(box, nil)
|
||||
return if selected.length == 0
|
||||
selected_pos = getBoxPosition(box, selected_index)
|
||||
able_count = 0
|
||||
new_held = []
|
||||
final_selected = []
|
||||
for index in selected
|
||||
pokemon = @storage[box, index]
|
||||
next if !pokemon
|
||||
able_count += 1 if pbAble?(pokemon)
|
||||
pos = getBoxPosition(box, index)
|
||||
new_held << [pokemon, pos[0] - selected_pos[0], pos[1] - selected_pos[1]]
|
||||
final_selected << index
|
||||
end
|
||||
|
||||
# Prevent taking last pokemon out of party
|
||||
if box == BOX_NAME && pbAbleCount == able_count
|
||||
if new_held.length > 1
|
||||
# deselect first able pokemon for convenience
|
||||
for i in 0...new_held.length
|
||||
if pbAble?(new_held[i][0])
|
||||
new_held.delete_at(i)
|
||||
final_selected.delete_at(i)
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
pbPlayBuzzerSE
|
||||
pbDisplay(_INTL("That's your last Pokémon!"))
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Clear selection, animate pickup, update logical state
|
||||
@multiSelectRange = nil
|
||||
@scene.pbUpdateSelectionRect(0, 0)
|
||||
@scene.animate_hold_multi(box, final_selected, selected_index) # animation
|
||||
@multiheldpkmn = new_held
|
||||
@storage.pbDeleteMulti(box, final_selected)
|
||||
@scene.pbRefresh
|
||||
end
|
||||
|
||||
# Check if all held pokémon can strictly fit at the target positions (no overlap, no OOB).
|
||||
# Commit them to storage and animate the placement.
|
||||
def pbPlaceMulti(box, selected_index)
|
||||
return if @multiheldpkmn.nil? || @multiheldpkmn.empty?
|
||||
|
||||
selected_pos = getBoxPosition(box, selected_index)
|
||||
if box >= 0
|
||||
# Validate every target slot is in-bounds and unoccupied
|
||||
need_fill = false
|
||||
for held in @multiheldpkmn
|
||||
held_x = held[1] + selected_pos[0]
|
||||
held_y = held[2] + selected_pos[1]
|
||||
if out_of_bounds?(box, held_x, held_y) || occupied?(box, held_x, held_y)
|
||||
need_fill = true
|
||||
end
|
||||
end
|
||||
if need_fill
|
||||
store_result = @storage.pbStoreBatch(@multiheldpkmn, box, selected_pos[0], selected_pos[1])
|
||||
if store_result == :CANT_PLACE || !store_result
|
||||
pbDisplay(_INTL("There's not enough room!"))
|
||||
return
|
||||
end
|
||||
@scene.animate_place_multi(box, selected_index)
|
||||
@multiheldpkmn = []
|
||||
@scene.pbHardRefresh
|
||||
|
||||
@scene.restartBox(self, @command, false)
|
||||
@storage = $PokemonStorage
|
||||
@scene.pbRefresh
|
||||
@multiheldpkmn = []
|
||||
@boxForMosaic = @storage.currentBox
|
||||
@selectionForMosaic = selected_index
|
||||
return store_result
|
||||
end
|
||||
|
||||
# All validated: animate then commit
|
||||
@scene.animate_place_multi(box, selected_index)
|
||||
for held in @multiheldpkmn
|
||||
pokemon = held[0]
|
||||
held_x = held[1] + selected_pos[0]
|
||||
held_y = held[2] + selected_pos[1]
|
||||
idx = held_x + held_y * PokemonBox::BOX_WIDTH
|
||||
@storage[box, idx] = pokemon
|
||||
end
|
||||
else
|
||||
# Party placement: validate space
|
||||
party_count = @storage.party.length
|
||||
if party_count + @multiheldpkmn.length > Settings::MAX_PARTY_SIZE
|
||||
pbDisplay(_INTL("There's not enough room!"))
|
||||
return
|
||||
end
|
||||
|
||||
@scene.animate_place_multi(box, selected_index)
|
||||
for held in @multiheldpkmn
|
||||
pokemon = held[0]
|
||||
@storage.party.push(pokemon)
|
||||
end
|
||||
end
|
||||
@scene.pbRefresh
|
||||
@multiheldpkmn = []
|
||||
end
|
||||
|
||||
# Validate release rules, animate release, then delete from storage
|
||||
def pbReleaseMulti(box)
|
||||
selected = getMultiSelection(box, nil)
|
||||
return if selected.length == 0
|
||||
able_count = 0
|
||||
final_released = []
|
||||
for index in selected
|
||||
pokemon = @storage[box, index]
|
||||
next if !pokemon
|
||||
if pokemon.owner.name == "RENTAL"
|
||||
pbDisplay(_INTL("This Pokémon cannot be released"))
|
||||
return
|
||||
elsif pokemon.egg?
|
||||
pbDisplay(_INTL("You can't release an Egg."))
|
||||
return false
|
||||
elsif pokemon.mail
|
||||
pbDisplay(_INTL("Please remove the mail."))
|
||||
return false
|
||||
end
|
||||
able_count += 1 if pbAble?(pokemon)
|
||||
final_released << index
|
||||
end
|
||||
|
||||
if box == BOX_NAME && pbAbleCount == able_count
|
||||
pbPlayBuzzerSE
|
||||
pbDisplay(_INTL("That's your last Pokémon!"))
|
||||
return
|
||||
end
|
||||
command = pbShowCommands(_INTL("Release {1} Pokémon?", final_released.length), [_INTL("No"), _INTL("Yes")])
|
||||
if command == 1
|
||||
command_confirm = pbShowCommands(_INTL("The {1} Pokémon will be lost forever. Release them?", final_released.length), [_INTL("No"), _INTL("Yes")])
|
||||
if command_confirm == 1
|
||||
@multiSelectRange = nil
|
||||
@scene.pbUpdateSelectionRect(0, 0)
|
||||
@scene.animate_release_multi(box, final_released)
|
||||
@storage.pbDeleteMulti(box, final_released)
|
||||
@scene.pbRefresh
|
||||
pbDisplay(_INTL("The Pokémon were released."))
|
||||
pbDisplay(_INTL("Bye-bye!"))
|
||||
@scene.pbRefresh
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
def out_of_bounds?(box, x, y)
|
||||
width = (box == BOX_NAME ? 2 : PokemonBox::BOX_WIDTH)
|
||||
height = (box == BOX_NAME ? (Settings::MAX_PARTY_SIZE / 2.0).ceil : PokemonBox::BOX_HEIGHT)
|
||||
x < 0 || y < 0 || x >= width || y >= height
|
||||
end
|
||||
|
||||
def occupied?(box, x, y)
|
||||
idx = x + y * PokemonBox::BOX_WIDTH
|
||||
!!@storage[box, idx]
|
||||
end
|
||||
|
||||
def pbMultiHeldPokemon
|
||||
@multiheldpkmn
|
||||
end
|
||||
|
||||
def pbHolding?
|
||||
return @heldpkmn != nil || (@multiheldpkmn && @multiheldpkmn.length > 0)
|
||||
end
|
||||
|
||||
def getSelectionRect(box, currentSelected)
|
||||
range_end = (currentSelected != nil ? currentSelected : @multiSelectRange && @multiSelectRange[1])
|
||||
return nil unless @multiSelectRange && @multiSelectRange[0] && range_end
|
||||
|
||||
box_width = box == BOX_NAME ? 2 : PokemonBox::BOX_WIDTH
|
||||
|
||||
ax = @multiSelectRange[0] % box_width
|
||||
ay = (@multiSelectRange[0].to_f / box_width).floor
|
||||
bx = range_end % box_width
|
||||
by = (range_end.to_f / box_width).floor
|
||||
|
||||
minx = [ax, bx].min
|
||||
miny = [ay, by].min
|
||||
maxx = [ax, bx].max
|
||||
maxy = [ay, by].max
|
||||
|
||||
Rect.new(minx, miny, maxx - minx + 1, maxy - miny + 1)
|
||||
end
|
||||
|
||||
def getMultiSelection(box, currentSelected)
|
||||
rect = getSelectionRect(box, currentSelected)
|
||||
return [] if rect.nil?
|
||||
|
||||
ret = []
|
||||
for j in (rect.y)..(rect.y + rect.height - 1)
|
||||
for i in (rect.x)..(rect.x + rect.width - 1)
|
||||
ret << getBoxIndex(box, i, j)
|
||||
end
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
def getBoxIndex(box, x, y)
|
||||
box_width = box == BOX_NAME ? 2 : PokemonBox::BOX_WIDTH
|
||||
x + y * box_width
|
||||
end
|
||||
|
||||
def getBoxPosition(box, index)
|
||||
box_width = box == BOX_NAME ? 2 : PokemonBox::BOX_WIDTH
|
||||
[index % box_width, (index.to_f / box_width).floor]
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,151 @@
|
||||
class PokemonStorageScreen
|
||||
# --- Define sortable criteria ---
|
||||
def sortable_criteria
|
||||
[
|
||||
{
|
||||
key: :dex,
|
||||
label: _INTL("By Pokédex number"),
|
||||
value_proc: ->(p) { p.id_number || 0 },
|
||||
friendly: [_INTL("Lowest to Highest Pokédex #"), _INTL("Highest to Lowest Pokédex #")]
|
||||
},
|
||||
{
|
||||
key: :head_dex,
|
||||
label: _INTL("By head Pokédex number"),
|
||||
value_proc: ->(p) { p.head_id || 0 },
|
||||
friendly: [_INTL("Lowest to Highest Pokédex #"), _INTL("Highest to Lowest Pokédex #")]
|
||||
},
|
||||
{
|
||||
key: :body_dex,
|
||||
label: _INTL("By body Pokédex number"),
|
||||
value_proc: ->(p) { p.body_id || 0 },
|
||||
friendly: [_INTL("Lowest to Highest Pokédex #"), _INTL("Highest to Lowest Pokédex #")]
|
||||
},
|
||||
{
|
||||
key: :alpha_species,
|
||||
label: _INTL("By species name"),
|
||||
value_proc: ->(p) { (p.species.to_s || "").downcase },
|
||||
friendly: [_INTL("A to Z"), _INTL("Z to A")]
|
||||
},
|
||||
{
|
||||
key: :alpha,
|
||||
label: _INTL("By nickname"),
|
||||
value_proc: ->(p) { (p.name || "").downcase },
|
||||
friendly: [_INTL("A to Z"), _INTL("Z to A")]
|
||||
},
|
||||
{
|
||||
key: :level,
|
||||
label: _INTL("By level"),
|
||||
value_proc: ->(p) { p.level || 0 },
|
||||
friendly: [_INTL("Lowest to Highest level"), _INTL("Highest to Lowest level")]
|
||||
},
|
||||
{
|
||||
key: :type,
|
||||
label: _INTL("By type"),
|
||||
value_proc: ->(p) {
|
||||
# Grab both types (fallbacks in case one is nil)
|
||||
t1 = p.type1 || :NORMAL
|
||||
t2 = p.type2 || ""
|
||||
[
|
||||
GameData::Type.get(t1).name,
|
||||
GameData::Type.get(t2).name
|
||||
]
|
||||
},
|
||||
friendly: [_INTL("A to Z by type"), _INTL("Z to A by type")]
|
||||
},
|
||||
{
|
||||
key: :date,
|
||||
label: _INTL("By date caught"),
|
||||
value_proc: ->(p) { p.timeReceived || Time.at(0) },
|
||||
friendly: [_INTL("Oldest to Newest"), _INTL("Newest to Oldest")]
|
||||
},
|
||||
{
|
||||
key: :invert,
|
||||
label: _INTL("Reverse"),
|
||||
value_proc: ->(p) { reverse },
|
||||
friendly: [_INTL("Reverse the order")]
|
||||
},
|
||||
{
|
||||
key: :random,
|
||||
label: _INTL("Shuffle"),
|
||||
value_proc: ->(p) { rand },
|
||||
friendly: [_INTL("Randomize the order")]
|
||||
},
|
||||
|
||||
]
|
||||
end
|
||||
|
||||
# --- Ask which criterion to sort by ---
|
||||
def pbAskSortCriterion
|
||||
commands = sortable_criteria.map { |c| c[:label] } + [_INTL("Cancel")]
|
||||
cmd = pbShowCommands(_INTL("Sort selected Pokémon how?"), commands)
|
||||
return nil if cmd == commands.length - 1
|
||||
return nil if cmd <= -1
|
||||
return cmd
|
||||
end
|
||||
|
||||
# --- Ask for order using friendly text ---
|
||||
def pbAskSortOrder(criterion_index)
|
||||
crit = sortable_criteria[criterion_index]
|
||||
orders = crit[:friendly] + [_INTL("Cancel")]
|
||||
ord = pbShowCommands(_INTL("Sort order?"), orders)
|
||||
return nil if ord <= -1
|
||||
return nil if ord == orders.length - 1
|
||||
return ord == 1 # true if descending
|
||||
end
|
||||
|
||||
# --- Sort the array according to criterion and order ---
|
||||
def sort_pokemon_array!(arr, criterion_index, descending)
|
||||
crit = sortable_criteria[criterion_index]
|
||||
if crit[:key] == :invert
|
||||
arr.reverse!
|
||||
return
|
||||
end
|
||||
arr.sort_by! { |p| crit[:value_proc].call(p) }
|
||||
arr.reverse! if descending
|
||||
end
|
||||
|
||||
# --- Main method stays mostly unchanged ---
|
||||
def pbSortMulti(box)
|
||||
selected = getMultiSelection(box, nil)
|
||||
return if selected.empty?
|
||||
|
||||
pokes = selected.map { |idx| @storage[box, idx] }.compact
|
||||
return if pokes.empty?
|
||||
|
||||
criterion = pbAskSortCriterion
|
||||
return if criterion.nil?
|
||||
|
||||
descending = pbAskSortOrder(criterion)
|
||||
return if descending.nil?
|
||||
|
||||
sort_pokemon_array!(pokes, criterion, descending)
|
||||
|
||||
# Clear selected slots
|
||||
selected.each { |idx| @storage[box, idx] = nil }
|
||||
|
||||
# Refill the rectangle row-by-row
|
||||
rect = getSelectionRect(box, nil)
|
||||
i = 0
|
||||
if rect
|
||||
for y in rect.y...(rect.y + rect.height)
|
||||
for x in rect.x...(rect.x + rect.width)
|
||||
break if i >= pokes.length
|
||||
idx = getBoxIndex(box, x, y)
|
||||
@storage[box, idx] = pokes[i]
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
else
|
||||
selected.each do |idx|
|
||||
break if i >= pokes.length
|
||||
@storage[box, idx] = pokes[i]
|
||||
i += 1
|
||||
end
|
||||
end
|
||||
|
||||
pbSEPlay("GUI party switch")
|
||||
@scene.pbHardRefresh
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
137
Data/Scripts/052_InfiniteFusion/Menus/PokemonSelection.rb
Normal file
137
Data/Scripts/052_InfiniteFusion/Menus/PokemonSelection.rb
Normal file
@@ -0,0 +1,137 @@
|
||||
#===============================================================================
|
||||
# * Pokémon Selection - by FL (Credits will be apreciated)
|
||||
#===============================================================================
|
||||
#
|
||||
# This script is for Pokémon Essentials. It makes a pokémon selection system
|
||||
# similar to Stadium/Battle Tower, where you can choose a certain number and
|
||||
# order of pokémon.
|
||||
#
|
||||
#===============================================================================
|
||||
#
|
||||
# To this script works, put it above main and use in script command
|
||||
# 'PokemonSelection.choose(min, max, canCancel, acceptFainted)' where min and
|
||||
# max are the minimum and maximum pokémon number selection (default values are
|
||||
# 1 and 6), canCancel when true the player can cancel the selection (default
|
||||
# is false) and acceptFainted that when true the player can choose fainted
|
||||
# pokémon and eggs (default is false). This method return if a party is choosen.
|
||||
#
|
||||
# To restore the previous party, use 'PokemonSelection.restore'. This do nothing
|
||||
# is there's no party to restore. Ths method returns if the party is restored.
|
||||
#
|
||||
# Between the two commands, don't allow the player to caught or deposit/withdraw
|
||||
# any pokémon or the pokémon will be lost! However, you pokémon can gain
|
||||
# exp/level, evolve, change hold item/moves normally. If you try to choose a
|
||||
# new party before restore the old one, the game raises an error. This won't
|
||||
# occurs if the previous selection is only an order change. ONLY in Debug mode
|
||||
# you get the phrase "Generate Pokemon teams for this challenge?", always
|
||||
# choose "No".
|
||||
#
|
||||
# 'PokemonSelection.hasValidTeam?(min, max, canCancel, acceptFainted)' returns
|
||||
# if your team is valid. If you try to use a invalid team (like putting the
|
||||
# minimum pokémon number as 3, but only having 2 pokémon), the selection is
|
||||
# treats as canceled. If the canCancel=false, the game goes in an infinite loop.
|
||||
#
|
||||
# Example: To make a 3vs3 battle, use 'PokemonSelection.choose(3,3)' and, after
|
||||
# the battle (regardless of result) use 'PokemonSelection.restore'. Only allows
|
||||
# the player to go in the battle if 'PokemonSelection.hasValidTeam?(3,3)' is
|
||||
# true, or set the minimum as 1.
|
||||
#
|
||||
# To perform only an order change, use
|
||||
# 'PokemonSelection.choose($Trainer,party.size,$Trainer,party.size,true,true)'.
|
||||
#
|
||||
# If you take a look in PokemonChallengeRules applications in scripts you can
|
||||
# customize some others choice conditions like have a certain level or ban
|
||||
# certain pokémon.
|
||||
#
|
||||
#===============================================================================
|
||||
|
||||
module PokemonSelection
|
||||
def self.rules(min=1, max=6, canCancel=false, acceptFainted=false)
|
||||
ret=PokemonChallengeRules.new
|
||||
# ret.setLevelAdjustment(OpenLevelAdjustment.new(PBExperience::MAXLEVEL))
|
||||
ret.addPokemonRule(AblePokemonRestriction.new) if !acceptFainted
|
||||
ret.ruleset.setNumberRange(min,max)
|
||||
return ret
|
||||
end
|
||||
|
||||
def self.hasValidTeam?(min=1, max=6, canCancel=false, acceptFainted=false)
|
||||
pbBattleChallenge.set("pokemonSelectionRules",7,self.rules(min,max))
|
||||
ret=pbHasEligible?
|
||||
pbBattleChallenge.pbCancel
|
||||
return ret
|
||||
end
|
||||
|
||||
def self.choose(min=1, max=6, canCancel=false, acceptFainted=false, ableproc=nil)
|
||||
if $PokemonGlobal.pokemonSelectionOriginalParty
|
||||
PokemonSelection.restore
|
||||
echoln "Can't choose a new party until restore the old one"
|
||||
end
|
||||
validPartyChosen=false
|
||||
pbBattleChallenge.set("pokemonSelectionRules",7,self.rules(min,max))
|
||||
loop do
|
||||
pbEntryScreen(ableproc)
|
||||
validPartyChosen=(pbBattleChallenge.getParty!=nil)
|
||||
break if(canCancel || validPartyChosen)
|
||||
Kernel.pbMessage(_INTL("Choose a Pokémon."))
|
||||
end
|
||||
if validPartyChosen
|
||||
# If the party size is the same, it is only an order change
|
||||
if($Trainer.party.size != pbBattleChallenge.getParty.size)
|
||||
$PokemonGlobal.pokemonSelectionOriginalParty=$Trainer.party
|
||||
end
|
||||
$Trainer.party=pbBattleChallenge.getParty
|
||||
end
|
||||
pbBattleChallenge.pbCancel
|
||||
return validPartyChosen
|
||||
end
|
||||
|
||||
def self.saveParty()
|
||||
$PokemonGlobal.pokemonSelectionOriginalParty=$Trainer.party
|
||||
end
|
||||
|
||||
|
||||
def self.restore(*args)
|
||||
hasSavedTeam=($PokemonGlobal.pokemonSelectionOriginalParty!=nil)
|
||||
if hasSavedTeam
|
||||
$Trainer.party=$PokemonGlobal.pokemonSelectionOriginalParty
|
||||
$PokemonGlobal.pokemonSelectionOriginalParty=nil
|
||||
end
|
||||
return hasSavedTeam
|
||||
end
|
||||
end
|
||||
|
||||
class PokemonRuleSet # Redefined to fix a bug
|
||||
def hasValidTeam?(team)
|
||||
if !team || team.length<self.minTeamLength
|
||||
return false
|
||||
end
|
||||
teamNumber=[self.maxLength,team.length].min
|
||||
validPokemon=[]
|
||||
for pokemon in team
|
||||
if isPokemonValid?(pokemon)
|
||||
validPokemon.push(pokemon)
|
||||
end
|
||||
end
|
||||
#if validPokemon.length<teamNumber # original
|
||||
if validPokemon.length<self.minLength # fixed
|
||||
return false
|
||||
end
|
||||
if @teamRules.length>0
|
||||
pbEachCombination(team,teamNumber){|comb|
|
||||
if isValid?(comb)
|
||||
return true
|
||||
end
|
||||
}
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
class BattleChallenge; def getParty; return @bc.party; end; end
|
||||
|
||||
class PokemonGlobalMetadata
|
||||
attr_accessor :pokemonSelectionOriginalParty
|
||||
attr_accessor :pokemonSelectionOriginalBag
|
||||
|
||||
end
|
||||
Reference in New Issue
Block a user