mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Rewrote load game screen inc. supporting multiple save files, allowed \PN and \v[42] in map names and Town Map point names
This commit is contained in:
@@ -6,6 +6,8 @@
|
|||||||
# @see SaveData.register_conversion
|
# @see SaveData.register_conversion
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
module SaveData
|
module SaveData
|
||||||
|
DIRECTORY = (File.directory?(System.data_directory)) ? System.data_directory : "./"
|
||||||
|
FILENAME_REGEX = /Game(\d*)\.rxdata$/
|
||||||
# Contains the file path of the save file.
|
# Contains the file path of the save file.
|
||||||
FILE_PATH = if File.directory?(System.data_directory)
|
FILE_PATH = if File.directory?(System.data_directory)
|
||||||
System.data_directory + "/Game.rxdata"
|
System.data_directory + "/Game.rxdata"
|
||||||
@@ -18,6 +20,19 @@ module SaveData
|
|||||||
return File.file?(FILE_PATH)
|
return File.file?(FILE_PATH)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# @return[Array] array of filenames in the save folder that are save files
|
||||||
|
def self.all_save_files
|
||||||
|
files = Dir.get(DIRECTORY, "*", false)
|
||||||
|
ret = []
|
||||||
|
files.each do |file|
|
||||||
|
next if !file[FILENAME_REGEX]
|
||||||
|
ret.push([$~[1].to_i, file])
|
||||||
|
end
|
||||||
|
ret.sort! { |a, b| a[0] <=> b[0] }
|
||||||
|
ret.map! { |val| val[1] }
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
# Fetches the save data from the given file.
|
# Fetches the save data from the given file.
|
||||||
# Returns an Array in the case of a pre-v19 save file.
|
# Returns an Array in the case of a pre-v19 save file.
|
||||||
# @param file_path [String] path of the file to load from
|
# @param file_path [String] path of the file to load from
|
||||||
@@ -64,9 +79,9 @@ module SaveData
|
|||||||
|
|
||||||
# Deletes the save file (and a possible .bak backup file if one exists)
|
# Deletes the save file (and a possible .bak backup file if one exists)
|
||||||
# @raise [Error::ENOENT]
|
# @raise [Error::ENOENT]
|
||||||
def self.delete_file
|
def self.delete_file(filename)
|
||||||
File.delete(FILE_PATH)
|
File.delete(DIRECTORY + filename)
|
||||||
File.delete(FILE_PATH + ".bak") if File.file?(FILE_PATH + ".bak")
|
File.delete(DIRECTORY + filename + ".bak") if File.file?(DIRECTORY + filename + ".bak")
|
||||||
end
|
end
|
||||||
|
|
||||||
# Converts the pre-v19 format data to the new format.
|
# Converts the pre-v19 format data to the new format.
|
||||||
|
|||||||
@@ -259,9 +259,9 @@ module SaveData
|
|||||||
# been set to be loaded during bootup. Done when a save file exists.
|
# been set to be loaded during bootup. Done when a save file exists.
|
||||||
# @param save_data [Hash] save data to load
|
# @param save_data [Hash] save data to load
|
||||||
# @raise [InvalidValueError] if an invalid value is being loaded
|
# @raise [InvalidValueError] if an invalid value is being loaded
|
||||||
def self.load_bootup_values(save_data)
|
def self.load_bootup_values(save_data, reload = false)
|
||||||
validate save_data => Hash
|
validate save_data => Hash
|
||||||
load_values(save_data) { |value| !value.loaded? && value.load_in_bootup? }
|
load_values(save_data) { |value| (reload || !value.loaded?) && value.load_in_bootup? }
|
||||||
end
|
end
|
||||||
|
|
||||||
# Goes through each value with {Value#load_in_bootup} enabled and loads their
|
# Goes through each value with {Value#load_in_bootup} enabled and loads their
|
||||||
|
|||||||
@@ -10,16 +10,17 @@ SaveData.register(:player) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
SaveData.register(:game_system) do
|
SaveData.register(:game_system) do
|
||||||
load_in_bootup
|
# TODO: Am I sure this doesn't need to be loaded in bootup?
|
||||||
|
# load_in_bootup
|
||||||
ensure_class :Game_System
|
ensure_class :Game_System
|
||||||
save_value { $game_system }
|
save_value { $game_system }
|
||||||
load_value { |value| $game_system = value }
|
load_value { |value| $game_system = value }
|
||||||
new_game_value { Game_System.new }
|
new_game_value { Game_System.new }
|
||||||
reset_on_new_game
|
# reset_on_new_game
|
||||||
end
|
end
|
||||||
|
|
||||||
SaveData.register(:pokemon_system) do
|
SaveData.register(:pokemon_system) do
|
||||||
load_in_bootup
|
load_in_bootup # Because this contains values for the Options screen
|
||||||
ensure_class :PokemonSystem
|
ensure_class :PokemonSystem
|
||||||
save_value { $PokemonSystem }
|
save_value { $PokemonSystem }
|
||||||
load_value { |value| $PokemonSystem = value }
|
load_value { |value| $PokemonSystem = value }
|
||||||
@@ -96,7 +97,6 @@ SaveData.register(:storage_system) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
SaveData.register(:essentials_version) do
|
SaveData.register(:essentials_version) do
|
||||||
load_in_bootup
|
|
||||||
ensure_class :String
|
ensure_class :String
|
||||||
save_value { Essentials::VERSION }
|
save_value { Essentials::VERSION }
|
||||||
load_value { |value| $save_engine_version = value }
|
load_value { |value| $save_engine_version = value }
|
||||||
@@ -104,7 +104,6 @@ SaveData.register(:essentials_version) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
SaveData.register(:game_version) do
|
SaveData.register(:game_version) do
|
||||||
load_in_bootup
|
|
||||||
ensure_class :String
|
ensure_class :String
|
||||||
save_value { Settings::GAME_VERSION }
|
save_value { Settings::GAME_VERSION }
|
||||||
load_value { |value| $save_game_version = value }
|
load_value { |value| $save_game_version = value }
|
||||||
@@ -112,10 +111,8 @@ SaveData.register(:game_version) do
|
|||||||
end
|
end
|
||||||
|
|
||||||
SaveData.register(:stats) do
|
SaveData.register(:stats) do
|
||||||
load_in_bootup
|
|
||||||
ensure_class :GameStats
|
ensure_class :GameStats
|
||||||
save_value { $stats }
|
save_value { $stats }
|
||||||
load_value { |value| $stats = value }
|
load_value { |value| $stats = value }
|
||||||
new_game_value { GameStats.new }
|
new_game_value { GameStats.new }
|
||||||
reset_on_new_game
|
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -23,16 +23,12 @@ module Game
|
|||||||
# Loads bootup data from save file (if it exists) or creates bootup data (if
|
# Loads bootup data from save file (if it exists) or creates bootup data (if
|
||||||
# it doesn't).
|
# it doesn't).
|
||||||
def set_up_system
|
def set_up_system
|
||||||
save_data = (SaveData.exists?) ? SaveData.read_from_file(SaveData::FILE_PATH) : {}
|
SaveData.initialize_bootup_values
|
||||||
if save_data.empty?
|
|
||||||
SaveData.initialize_bootup_values
|
|
||||||
else
|
|
||||||
SaveData.load_bootup_values(save_data)
|
|
||||||
end
|
|
||||||
# Set resize factor
|
|
||||||
pbSetResizeFactor([$PokemonSystem.screensize, 4].min)
|
pbSetResizeFactor([$PokemonSystem.screensize, 4].min)
|
||||||
# Set language (and choose language if there is no save file)
|
# Set language (and choose language if there is no save file)
|
||||||
if !Settings::LANGUAGES.empty?
|
if !Settings::LANGUAGES.empty?
|
||||||
|
# TODO: Change this to check for any save file.
|
||||||
|
save_data = (SaveData.exists?) ? SaveData.read_from_file(SaveData::FILE_PATH) : {}
|
||||||
$PokemonSystem.language = pbChooseLanguage if save_data.empty? && Settings::LANGUAGES.length >= 2
|
$PokemonSystem.language = pbChooseLanguage if save_data.empty? && Settings::LANGUAGES.length >= 2
|
||||||
MessageTypes.load_message_files(Settings::LANGUAGES[$PokemonSystem.language][1])
|
MessageTypes.load_message_files(Settings::LANGUAGES[$PokemonSystem.language][1])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ class GameStats
|
|||||||
attr_writer :play_time # In seconds; the reader also updates the value
|
attr_writer :play_time # In seconds; the reader also updates the value
|
||||||
attr_accessor :play_sessions
|
attr_accessor :play_sessions
|
||||||
attr_accessor :time_last_saved # In seconds
|
attr_accessor :time_last_saved # In seconds
|
||||||
|
attr_reader :real_time_saved
|
||||||
|
|
||||||
def initialize
|
def initialize
|
||||||
# Travel
|
# Travel
|
||||||
@@ -149,6 +150,7 @@ class GameStats
|
|||||||
@play_time = 0
|
@play_time = 0
|
||||||
@play_sessions = 0
|
@play_sessions = 0
|
||||||
@time_last_saved = 0
|
@time_last_saved = 0
|
||||||
|
@real_time_saved = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def distance_moved
|
def distance_moved
|
||||||
@@ -189,6 +191,7 @@ class GameStats
|
|||||||
|
|
||||||
def set_time_last_saved
|
def set_time_last_saved
|
||||||
@time_last_saved = play_time
|
@time_last_saved = play_time
|
||||||
|
@real_time_saved = Time.now.to_i
|
||||||
end
|
end
|
||||||
|
|
||||||
def time_since_last_save
|
def time_since_last_save
|
||||||
|
|||||||
@@ -243,17 +243,15 @@ end
|
|||||||
def pbRepositionMessageWindow(msgwindow, linecount = 2)
|
def pbRepositionMessageWindow(msgwindow, linecount = 2)
|
||||||
msgwindow.height = (32 * linecount) + msgwindow.borderY
|
msgwindow.height = (32 * linecount) + msgwindow.borderY
|
||||||
msgwindow.y = (Graphics.height) - (msgwindow.height)
|
msgwindow.y = (Graphics.height) - (msgwindow.height)
|
||||||
if $game_system
|
case $game_system&.message_position || 2
|
||||||
case $game_system.message_position
|
when 0 # top
|
||||||
when 0 # up
|
msgwindow.y = 0
|
||||||
msgwindow.y = 0
|
when 1 # middle
|
||||||
when 1 # middle
|
msgwindow.y = (Graphics.height - msgwindow.height) / 2
|
||||||
msgwindow.y = (Graphics.height / 2) - (msgwindow.height / 2)
|
when 2 # bottom
|
||||||
when 2
|
msgwindow.y = Graphics.height - msgwindow.height
|
||||||
msgwindow.y = (Graphics.height) - (msgwindow.height)
|
|
||||||
end
|
|
||||||
msgwindow.opacity = 0 if $game_system.message_frame != 0
|
|
||||||
end
|
end
|
||||||
|
msgwindow.opacity = 0 if ($game_system&.message_frame || 0) != 0
|
||||||
end
|
end
|
||||||
|
|
||||||
# internal function
|
# internal function
|
||||||
|
|||||||
@@ -254,9 +254,10 @@ end
|
|||||||
|
|
||||||
def pbGetMapNameFromId(id)
|
def pbGetMapNameFromId(id)
|
||||||
name = GameData::MapMetadata.try_get(id)&.name
|
name = GameData::MapMetadata.try_get(id)&.name
|
||||||
if nil_or_empty?(name)
|
name = pbGetBasicMapNameFromId(id) if nil_or_empty?(name)
|
||||||
name = pbGetBasicMapNameFromId(id)
|
name = name.gsub(/\\PN/, $player.name) if $player
|
||||||
name.gsub!(/\\PN/, $player.name) if $player
|
if $game_variables
|
||||||
|
name = name.gsub(/\\v\[(\d+)\]/) { |num| $game_variables[$~[1].to_i].to_s }
|
||||||
end
|
end
|
||||||
return name
|
return name
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ module GameData
|
|||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: Make the below depend on a Setting rather than quoting it out.
|
||||||
def display_type(pkmn, move = nil)
|
def display_type(pkmn, move = nil)
|
||||||
=begin
|
=begin
|
||||||
case @function_code
|
case @function_code
|
||||||
@@ -187,6 +188,7 @@ module GameData
|
|||||||
return @type
|
return @type
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: Make the below depend on a Setting rather than quoting it out.
|
||||||
def display_damage(pkmn, move = nil)
|
def display_damage(pkmn, move = nil)
|
||||||
=begin
|
=begin
|
||||||
case @function_code
|
case @function_code
|
||||||
|
|||||||
@@ -159,6 +159,7 @@ class Battle::Move
|
|||||||
if battler.isSpecies?(:MORPEKO) || battler.effects[PBEffects::TransformSpecies] == :MORPEKO
|
if battler.isSpecies?(:MORPEKO) || battler.effects[PBEffects::TransformSpecies] == :MORPEKO
|
||||||
return pbBaseType(battler)
|
return pbBaseType(battler)
|
||||||
end
|
end
|
||||||
|
# TODO: Make the below depend on a Setting rather than quoting it out.
|
||||||
=begin
|
=begin
|
||||||
when "TypeDependsOnUserPlate", "TypeDependsOnUserMemory",
|
when "TypeDependsOnUserPlate", "TypeDependsOnUserMemory",
|
||||||
"TypeDependsOnUserDrive", "TypeAndPowerDependOnUserBerry",
|
"TypeDependsOnUserDrive", "TypeAndPowerDependOnUserBerry",
|
||||||
@@ -170,6 +171,7 @@ class Battle::Move
|
|||||||
return @realMove.display_type(battler.pokemon)
|
return @realMove.display_type(battler.pokemon)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: Make the below depend on a Setting rather than quoting it out.
|
||||||
def display_damage(battler)
|
def display_damage(battler)
|
||||||
=begin
|
=begin
|
||||||
case @function_code
|
case @function_code
|
||||||
@@ -185,6 +187,7 @@ class Battle::Move
|
|||||||
return @realMove.display_damage(battler.pokemon)
|
return @realMove.display_damage(battler.pokemon)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# TODO: Make the below depend on a Setting rather than quoting it out.
|
||||||
def display_category(battler)
|
def display_category(battler)
|
||||||
=begin
|
=begin
|
||||||
case @function_code
|
case @function_code
|
||||||
|
|||||||
@@ -90,16 +90,7 @@ class IntroEventScene < EventScene
|
|||||||
|
|
||||||
def close_title_screen(scene, *args)
|
def close_title_screen(scene, *args)
|
||||||
fade_out_title_screen(scene)
|
fade_out_title_screen(scene)
|
||||||
sscene = PokemonLoad_Scene.new
|
UI::Load.new.main
|
||||||
sscreen = PokemonLoadScreen.new(sscene)
|
|
||||||
sscreen.pbStartLoadScreen
|
|
||||||
end
|
|
||||||
|
|
||||||
def close_title_screen_delete(scene, *args)
|
|
||||||
fade_out_title_screen(scene)
|
|
||||||
sscene = PokemonLoad_Scene.new
|
|
||||||
sscreen = PokemonLoadScreen.new(sscene)
|
|
||||||
sscreen.pbStartDeleteScreen
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def title_screen_update(scene, args)
|
def title_screen_update(scene, args)
|
||||||
@@ -108,11 +99,6 @@ class IntroEventScene < EventScene
|
|||||||
@pic2.moveOpacity(TICKS_PER_ENTER_FLASH * 2 / 10, TICKS_PER_ENTER_FLASH * 4 / 10, 0)
|
@pic2.moveOpacity(TICKS_PER_ENTER_FLASH * 2 / 10, TICKS_PER_ENTER_FLASH * 4 / 10, 0)
|
||||||
@pic2.moveOpacity(TICKS_PER_ENTER_FLASH * 6 / 10, TICKS_PER_ENTER_FLASH * 4 / 10, 255)
|
@pic2.moveOpacity(TICKS_PER_ENTER_FLASH * 6 / 10, TICKS_PER_ENTER_FLASH * 4 / 10, 255)
|
||||||
end
|
end
|
||||||
if Input.press?(Input::DOWN) &&
|
|
||||||
Input.press?(Input::BACK) &&
|
|
||||||
Input.press?(Input::CTRL)
|
|
||||||
close_title_screen_delete(scene, args)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -186,6 +186,8 @@ class PokemonRegionMap_Scene
|
|||||||
next if point[0] != x || point[1] != y
|
next if point[0] != x || point[1] != y
|
||||||
return "" if point[7] && (@wallmap || point[7] <= 0 || !$game_switches[point[7]])
|
return "" if point[7] && (@wallmap || point[7] <= 0 || !$game_switches[point[7]])
|
||||||
name = pbGetMessageFromHash(MessageTypes::REGION_LOCATION_NAMES, point[2])
|
name = pbGetMessageFromHash(MessageTypes::REGION_LOCATION_NAMES, point[2])
|
||||||
|
name = name.gsub(/\\PN/, $player.name)
|
||||||
|
name = name.gsub(/\\v\[(\d+)\]/) { |num| $game_variables[$~[1].to_i].to_s }
|
||||||
return (@editor) ? point[2] : name
|
return (@editor) ? point[2] : name
|
||||||
end
|
end
|
||||||
return ""
|
return ""
|
||||||
@@ -336,7 +338,7 @@ class PokemonRegionMapScreen
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pbStartScreen
|
def pbStartScreen
|
||||||
@scene.pbStartScene($DEBUG)
|
@scene.pbStartScene # ($DEBUG)
|
||||||
ret = @scene.pbMapScene
|
ret = @scene.pbMapScene
|
||||||
@scene.pbEndScene
|
@scene.pbEndScene
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@@ -392,7 +392,7 @@ MenuHandlers.add(:options_menu, :bgm_volume, {
|
|||||||
"set_proc" => proc { |value, scene|
|
"set_proc" => proc { |value, scene|
|
||||||
next if $PokemonSystem.bgmvolume == value
|
next if $PokemonSystem.bgmvolume == value
|
||||||
$PokemonSystem.bgmvolume = value
|
$PokemonSystem.bgmvolume = value
|
||||||
next if scene.in_load_screen || $game_system.playing_bgm.nil?
|
next if scene.in_load_screen || !$game_system || $game_system.playing_bgm.nil?
|
||||||
playingBGM = $game_system.getPlayingBGM
|
playingBGM = $game_system.getPlayingBGM
|
||||||
$game_system.bgm_pause
|
$game_system.bgm_pause
|
||||||
$game_system.bgm_resume(playingBGM)
|
$game_system.bgm_resume(playingBGM)
|
||||||
@@ -409,7 +409,7 @@ MenuHandlers.add(:options_menu, :se_volume, {
|
|||||||
"set_proc" => proc { |value, _scene|
|
"set_proc" => proc { |value, _scene|
|
||||||
next if $PokemonSystem.sevolume == value
|
next if $PokemonSystem.sevolume == value
|
||||||
$PokemonSystem.sevolume = value
|
$PokemonSystem.sevolume = value
|
||||||
if $game_system.playing_bgs
|
if $game_system && $game_system.playing_bgs
|
||||||
$game_system.playing_bgs.volume = value
|
$game_system.playing_bgs.volume = value
|
||||||
playingBGS = $game_system.getPlayingBGS
|
playingBGS = $game_system.getPlayingBGS
|
||||||
$game_system.bgs_pause
|
$game_system.bgs_pause
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ module UI
|
|||||||
end
|
end
|
||||||
|
|
||||||
def gendered_filename(base_filename)
|
def gendered_filename(base_filename)
|
||||||
return filename_with_appendix(base_filename, "_f") if $player.female?
|
return filename_with_appendix(base_filename, "_f") if $player&.female?
|
||||||
return base_filename
|
return base_filename
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -306,6 +306,8 @@ module UI
|
|||||||
# The visuals class.
|
# The visuals class.
|
||||||
#=============================================================================
|
#=============================================================================
|
||||||
class BaseVisuals
|
class BaseVisuals
|
||||||
|
attr_reader :sprites
|
||||||
|
|
||||||
BACKGROUND_FILENAME = "bg"
|
BACKGROUND_FILENAME = "bg"
|
||||||
|
|
||||||
include SpriteContainerMixin
|
include SpriteContainerMixin
|
||||||
@@ -800,6 +802,7 @@ module UI
|
|||||||
end
|
end
|
||||||
|
|
||||||
def main
|
def main
|
||||||
|
return if @disposed
|
||||||
start_screen
|
start_screen
|
||||||
loop do
|
loop do
|
||||||
on_start_main_loop
|
on_start_main_loop
|
||||||
|
|||||||
@@ -327,7 +327,6 @@ end
|
|||||||
#
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class UI::PartyVisuals < UI::BaseVisuals
|
class UI::PartyVisuals < UI::BaseVisuals
|
||||||
attr_reader :sprites
|
|
||||||
attr_reader :index
|
attr_reader :index
|
||||||
attr_reader :sub_mode
|
attr_reader :sub_mode
|
||||||
|
|
||||||
|
|||||||
@@ -164,7 +164,6 @@ end
|
|||||||
#
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class UI::BagVisuals < UI::BaseVisuals
|
class UI::BagVisuals < UI::BaseVisuals
|
||||||
attr_reader :sprites
|
|
||||||
attr_reader :pocket
|
attr_reader :pocket
|
||||||
|
|
||||||
GRAPHICS_FOLDER = "Bag/" # Subfolder in Graphics/UI
|
GRAPHICS_FOLDER = "Bag/" # Subfolder in Graphics/UI
|
||||||
|
|||||||
717
Data/Scripts/016b_UI redesign/013_UI_Load.rb
Normal file
717
Data/Scripts/016b_UI redesign/013_UI_Load.rb
Normal file
@@ -0,0 +1,717 @@
|
|||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
|
#===============================================================================
|
||||||
|
class UI::LoadPanel < UI::SpriteContainer
|
||||||
|
GRAPHICS_FOLDER = "Load/"
|
||||||
|
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
|
||||||
|
:default => [Color.new(88, 88, 80), Color.new(168, 184, 184)] # Base and shadow colour
|
||||||
|
}
|
||||||
|
PANEL_WIDTH = 392
|
||||||
|
PANEL_HEIGHT = 56
|
||||||
|
|
||||||
|
def initialize(label, viewport)
|
||||||
|
@label = label
|
||||||
|
@selected = nil
|
||||||
|
super(viewport)
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_sprites
|
||||||
|
initialize_panel_background
|
||||||
|
initialize_overlay
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_panel_background
|
||||||
|
@sprites[:background] = ChangelingSprite.new(0, 0, @viewport)
|
||||||
|
panel_srcs.each_pair do |key, values|
|
||||||
|
@sprites[:background].add_bitmap(key, values)
|
||||||
|
end
|
||||||
|
@sprites[:background].change_bitmap(:default)
|
||||||
|
record_values(:background)
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_overlay
|
||||||
|
add_overlay(:overlay, @sprites[:background].src_rect.width, @sprites[:background].src_rect.height)
|
||||||
|
@sprites[:overlay].z = 10
|
||||||
|
record_values(:overlay)
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def width
|
||||||
|
return self.class::PANEL_WIDTH
|
||||||
|
end
|
||||||
|
|
||||||
|
def height
|
||||||
|
return self.class::PANEL_HEIGHT
|
||||||
|
end
|
||||||
|
|
||||||
|
def panel_srcs
|
||||||
|
return {
|
||||||
|
:default => [graphics_folder + "panels", 0, UI::LoadContinuePanel::PANEL_HEIGHT * 2,
|
||||||
|
self.class::PANEL_WIDTH, self.class::PANEL_HEIGHT],
|
||||||
|
:selected => [graphics_folder + "panels", 0, (UI::LoadContinuePanel::PANEL_HEIGHT * 2) + self.class::PANEL_HEIGHT,
|
||||||
|
self.class::PANEL_WIDTH, self.class::PANEL_HEIGHT]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def selected=(value)
|
||||||
|
return if @selected == value
|
||||||
|
@selected = value
|
||||||
|
@sprites[:background].change_bitmap((@selected) ? :selected : :default)
|
||||||
|
refresh
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def refresh
|
||||||
|
super
|
||||||
|
draw_text(@label, 18, 18)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
|
#===============================================================================
|
||||||
|
class UI::LoadContinuePanel < UI::LoadPanel
|
||||||
|
attr_reader :sprites
|
||||||
|
|
||||||
|
GRAPHICS_FOLDER = "Load/"
|
||||||
|
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
|
||||||
|
:default => [Color.new(88, 88, 80), Color.new(168, 184, 184)], # Base and shadow colour
|
||||||
|
:male => [Color.new(0, 112, 248), Color.new(120, 184, 232)],
|
||||||
|
:female => [Color.new(232, 32, 16), Color.new(248, 168, 184)]
|
||||||
|
}
|
||||||
|
PANEL_WIDTH = 392
|
||||||
|
PANEL_HEIGHT = 248
|
||||||
|
|
||||||
|
def initialize(label, save_data, slot_index, total_slots, viewport)
|
||||||
|
@save_data = save_data
|
||||||
|
@slot_index = slot_index
|
||||||
|
@total_slots = total_slots
|
||||||
|
super(label, viewport)
|
||||||
|
refresh
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_sprites
|
||||||
|
super
|
||||||
|
initialize_player_sprite
|
||||||
|
initialize_pokemon_icons
|
||||||
|
initialize_arrow_sprites
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_player_sprite
|
||||||
|
meta = GameData::PlayerMetadata.get(@save_data[:player].character_ID)
|
||||||
|
filename = pbGetPlayerCharset(meta.walk_charset, @save_data[:player], true)
|
||||||
|
@sprites[:player] = TrainerWalkingCharSprite.new(filename, @viewport)
|
||||||
|
if !@sprites[:player].bitmap
|
||||||
|
raise _INTL("Player character {1}'s walking charset was not found (filename: \"{2}\").",
|
||||||
|
@save_data[:player].character_ID, filename)
|
||||||
|
end
|
||||||
|
@sprites[:player].x = 48 - (@sprites[:player].bitmap.width / 8)
|
||||||
|
@sprites[:player].y = 72 - (@sprites[:player].bitmap.height / 8)
|
||||||
|
@sprites[:player].z = 1
|
||||||
|
record_values(:player)
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_pokemon_icons
|
||||||
|
Settings::MAX_PARTY_SIZE.times do |i|
|
||||||
|
@sprites["pokemon_#{i}"] = PokemonIconSprite.new(@save_data[:player].party[i], @viewport)
|
||||||
|
@sprites["pokemon_#{i}"].x, @sprites["pokemon_#{i}"].y = pokemon_coords(i)
|
||||||
|
@sprites["pokemon_#{i}"].z = 1
|
||||||
|
@sprites["pokemon_#{i}"].setOffset
|
||||||
|
record_values("pokemon_#{i}")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_arrow_sprites
|
||||||
|
@sprites[:left_arrow] = AnimatedSprite.new(UI_FOLDER + "left_arrow", 8, 40, 28, 2, @viewport)
|
||||||
|
@sprites[:left_arrow].x = -16
|
||||||
|
@sprites[:left_arrow].y = (height / 2) - 14
|
||||||
|
@sprites[:left_arrow].z = 20
|
||||||
|
@sprites[:left_arrow].play
|
||||||
|
record_values(:left_arrow)
|
||||||
|
@sprites[:right_arrow] = AnimatedSprite.new(UI_FOLDER + "right_arrow", 8, 40, 28, 2, @viewport)
|
||||||
|
@sprites[:right_arrow].x = width - 24
|
||||||
|
@sprites[:right_arrow].y = (height / 2) - 14
|
||||||
|
@sprites[:right_arrow].z = 20
|
||||||
|
@sprites[:right_arrow].play
|
||||||
|
record_values(:right_arrow)
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def panel_srcs
|
||||||
|
return {
|
||||||
|
:default => [graphics_folder + "panels", 0, 0,
|
||||||
|
self.class::PANEL_WIDTH, self.class::PANEL_HEIGHT],
|
||||||
|
:selected => [graphics_folder + "panels", 0, self.class::PANEL_HEIGHT,
|
||||||
|
self.class::PANEL_WIDTH, self.class::PANEL_HEIGHT]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def pokemon_coords(index)
|
||||||
|
return 276 + (66 * (index % 2)),
|
||||||
|
74 + (50 * (index / 2))
|
||||||
|
end
|
||||||
|
|
||||||
|
def visible=(value)
|
||||||
|
super
|
||||||
|
@sprites[:left_arrow].visible = (@selected && @total_slots >= 2)
|
||||||
|
@sprites[:right_arrow].visible = (@selected && @total_slots >= 2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def selected=(value)
|
||||||
|
@sprites[:left_arrow].visible = (value && @total_slots >= 2)
|
||||||
|
@sprites[:right_arrow].visible = (value && @total_slots >= 2)
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_data(save_data, slot_index, total_slots)
|
||||||
|
@save_data = save_data
|
||||||
|
@slot_index = slot_index
|
||||||
|
@total_slots = total_slots
|
||||||
|
@sprites[:left_arrow].visible = (@selected && total_slots >= 2)
|
||||||
|
@sprites[:right_arrow].visible = (@selected && total_slots >= 2)
|
||||||
|
set_player_sprite
|
||||||
|
refresh
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_player_sprite
|
||||||
|
meta = GameData::PlayerMetadata.get(@save_data[:player].character_ID)
|
||||||
|
filename = pbGetPlayerCharset(meta.walk_charset, @save_data[:player], true)
|
||||||
|
@sprites[:player].charset = filename
|
||||||
|
if !@sprites[:player].bitmap
|
||||||
|
raise _INTL("Player character {1}'s walking charset was not found (filename: \"{2}\").",
|
||||||
|
@save_data[:player].character_ID, filename)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def refresh
|
||||||
|
super
|
||||||
|
refresh_pokemon
|
||||||
|
draw_slot_number
|
||||||
|
draw_save_file_text
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_pokemon
|
||||||
|
Settings::MAX_PARTY_SIZE.times do |i|
|
||||||
|
@sprites["pokemon_#{i}"].pokemon = @save_data[:player].party[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_slot_number
|
||||||
|
return if @total_slots <= 1
|
||||||
|
draw_text(sprintf("%d/%d", @slot_index + 1, @total_slots), PANEL_WIDTH - 18, 18, align: :right)
|
||||||
|
end
|
||||||
|
|
||||||
|
def draw_save_file_text
|
||||||
|
gender_theme = :default
|
||||||
|
if @save_data[:player].male?
|
||||||
|
gender_theme = :male
|
||||||
|
elsif @save_data[:player].female?
|
||||||
|
gender_theme = :female
|
||||||
|
end
|
||||||
|
# Player's name
|
||||||
|
draw_text(@save_data[:player].name, 78, 66, theme: gender_theme)
|
||||||
|
# Location
|
||||||
|
map_id = @save_data[:map_factory].map.map_id
|
||||||
|
map_name = pbGetMapNameFromId(map_id)
|
||||||
|
map_name = map_name.gsub(/\\PN/, @save_data[:player].name)
|
||||||
|
map_name = map_name.gsub(/\\v\[(\d+)\]/) { |num| @save_data[:variables][$~[1].to_i].to_s }
|
||||||
|
draw_text(map_name, 18, 114, theme: gender_theme)
|
||||||
|
# Gym Badges
|
||||||
|
draw_text(_INTL("Badges:"), 18, 146)
|
||||||
|
draw_text(@save_data[:player].badge_count.to_s, 156, 146, theme: gender_theme)
|
||||||
|
# Pokédex owned count
|
||||||
|
draw_text(_INTL("Pokédex:"), 18, 178)
|
||||||
|
draw_text(@save_data[:player].pokedex.seen_count.to_s, 156, 178, theme: gender_theme)
|
||||||
|
# Time played
|
||||||
|
draw_text(_INTL("Time played:"), 18, 210)
|
||||||
|
play_time = @save_data[:stats]&.play_time.to_i || 0
|
||||||
|
hour = (play_time / 60) / 60
|
||||||
|
min = (play_time / 60) % 60
|
||||||
|
play_time_text = (hour > 0) ? _INTL("{1}h {2}m", hour, min) : _INTL("{1}m", min)
|
||||||
|
draw_text(play_time_text, 156, 210, theme: gender_theme)
|
||||||
|
save_time = @save_data[:stats]&.real_time_saved
|
||||||
|
if save_time
|
||||||
|
save_time = Time.at(save_time)
|
||||||
|
if System.user_language[3..4] == "US" # If the user is in the United States
|
||||||
|
save_text = save_time.strftime("%-m/&-d/%Y")
|
||||||
|
else
|
||||||
|
save_text = save_time.strftime("%-d/%-m/%Y")
|
||||||
|
end
|
||||||
|
draw_text(save_text, PANEL_WIDTH - 18, 210, align: :right, theme: gender_theme)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_existing_pokemon
|
||||||
|
Settings::MAX_PARTY_SIZE.times do |i|
|
||||||
|
@sprites["pokemon_#{i}"].pokemon = @save_data[:player].party[i]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
|
#===============================================================================
|
||||||
|
class UI::LoadVisuals < UI::BaseVisuals
|
||||||
|
attr_reader :slot_index
|
||||||
|
|
||||||
|
GRAPHICS_FOLDER = "Load/" # Subfolder in Graphics/UI
|
||||||
|
PANEL_SPACING_EDGE = 4
|
||||||
|
PANEL_SPACING = PANEL_SPACING_EDGE * 2
|
||||||
|
|
||||||
|
# save_data here is an array of all save files' data. It has been compacted.
|
||||||
|
# commands is {:continue => _INTL("Continue"), :new_game => _INTL("New Game")}, etc.
|
||||||
|
def initialize(commands, save_data, default_slot_index = 0)
|
||||||
|
@save_data = save_data
|
||||||
|
@commands = commands
|
||||||
|
@index = @commands.keys.first # A symbol from @commands
|
||||||
|
@slot_index = default_slot_index # Which save slot is selected
|
||||||
|
super()
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_sprites
|
||||||
|
initialize_continue_panels
|
||||||
|
initialize_other_panels
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_continue_panels
|
||||||
|
return if @save_data.nil? || @commands.keys.first != :continue
|
||||||
|
# Continue panel in middle
|
||||||
|
this_slot_index = @slot_index
|
||||||
|
@sprites[:continue] = create_continue_panel(this_slot_index)
|
||||||
|
# Continue panel to left
|
||||||
|
if @save_data.length >= 2
|
||||||
|
previous_slot_index = this_slot_index - 1
|
||||||
|
@sprites[:continue_previous] = create_continue_panel(this_slot_index - 1)
|
||||||
|
@sprites[:continue_previous].x = @sprites[:continue].x - @sprites[:continue].width - PANEL_SPACING
|
||||||
|
# Continue panel to right
|
||||||
|
next_slot_index = this_slot_index + 1
|
||||||
|
@sprites[:continue_next] = create_continue_panel(this_slot_index + 1)
|
||||||
|
@sprites[:continue_next].x = @sprites[:continue].x + @sprites[:continue].width + PANEL_SPACING
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_other_panels
|
||||||
|
@commands.each_pair do |key, text|
|
||||||
|
next if key == :continue
|
||||||
|
@sprites[key] = UI::LoadPanel.new(text, @viewport)
|
||||||
|
@sprites[key].x = (Graphics.width - @sprites[key].width) / 2
|
||||||
|
end
|
||||||
|
@sprites[:mystery_gift]&.visible = @save_data[@slot_index] && @save_data[@slot_index][1][:player].mystery_gift_unlocked
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def create_continue_panel(slot_index)
|
||||||
|
slot_index += @save_data.length if slot_index < 0
|
||||||
|
slot_index -= @save_data.length if slot_index >= @save_data.length
|
||||||
|
ret = UI::LoadContinuePanel.new(@commands[:continue],
|
||||||
|
@save_data[slot_index][1], slot_index, @save_data.length, @viewport)
|
||||||
|
ret.x = (Graphics.width - ret.width) / 2
|
||||||
|
return ret
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_index(new_index)
|
||||||
|
@index = new_index
|
||||||
|
refresh_on_index_changed(@index)
|
||||||
|
end
|
||||||
|
|
||||||
|
def go_to_next_option(play_se = true)
|
||||||
|
return if @commands.length == 1
|
||||||
|
old_index = @commands.keys.index(@index)
|
||||||
|
new_index = old_index
|
||||||
|
loop do
|
||||||
|
new_index = (new_index + 1) % @commands.length
|
||||||
|
break if @sprites[@commands.keys[new_index]] && @sprites[@commands.keys[new_index]].visible
|
||||||
|
break if new_index == old_index
|
||||||
|
end
|
||||||
|
return if new_index == old_index
|
||||||
|
pbPlayCursorSE if play_se
|
||||||
|
set_index(@commands.keys[new_index])
|
||||||
|
end
|
||||||
|
|
||||||
|
def go_to_previous_option(play_se = true)
|
||||||
|
return if @commands.length == 1
|
||||||
|
old_index = @commands.keys.index(@index)
|
||||||
|
new_index = old_index
|
||||||
|
loop do
|
||||||
|
new_index -= 1
|
||||||
|
new_index += @commands.length if new_index < 0
|
||||||
|
break if @sprites[@commands.keys[new_index]] && @sprites[@commands.keys[new_index]].visible
|
||||||
|
break if new_index == old_index
|
||||||
|
end
|
||||||
|
return if new_index == old_index
|
||||||
|
pbPlayCursorSE if play_se
|
||||||
|
set_index(@commands.keys[new_index])
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def set_slot_index(new_index, forced = false)
|
||||||
|
while new_index < 0
|
||||||
|
new_index += @save_data.length
|
||||||
|
end
|
||||||
|
while new_index >= @save_data.length
|
||||||
|
new_index -= @save_data.length
|
||||||
|
end
|
||||||
|
return if !forced && @slot_index == new_index
|
||||||
|
# Set the new index
|
||||||
|
@slot_index = new_index
|
||||||
|
# Show the newly selected slot's information in the Continue panel
|
||||||
|
@sprites[:continue].set_data(@save_data[@slot_index][1], @slot_index, @save_data.length)
|
||||||
|
# Show the newly adjacent slots' information in the adjacent Continue panels
|
||||||
|
prev_index = @slot_index - 1
|
||||||
|
prev_index += @save_data.length if prev_index < 0
|
||||||
|
@sprites[:continue_previous]&.set_data(@save_data[prev_index][1], prev_index, @save_data.length)
|
||||||
|
next_index = (@slot_index + 1) % @save_data.length
|
||||||
|
@sprites[:continue_next]&.set_data(@save_data[next_index][1], next_index, @save_data.length)
|
||||||
|
# Determine whether the Mystery Gift option is visible
|
||||||
|
@sprites[:mystery_gift].visible = @save_data[@slot_index][1][:player].mystery_gift_unlocked
|
||||||
|
refresh_panel_positions
|
||||||
|
SaveData.load_bootup_values(@save_data[@slot_index][1], true)
|
||||||
|
pbPlayCursorSE if !forced
|
||||||
|
end
|
||||||
|
|
||||||
|
def go_to_next_save_slot
|
||||||
|
set_slot_index(@slot_index + 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def go_to_previous_save_slot
|
||||||
|
set_slot_index(@slot_index - 1)
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def refresh
|
||||||
|
super
|
||||||
|
@commands.keys.each { |key| @sprites[key]&.refresh }
|
||||||
|
refresh_panel_positions
|
||||||
|
refresh_selected_panel
|
||||||
|
end
|
||||||
|
|
||||||
|
def full_refresh
|
||||||
|
refresh
|
||||||
|
@sprites.each_pair { |key, sprite| sprite.refresh if sprite.respond_to?(:refresh) }
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_panel_positions
|
||||||
|
@panel_y_offset ||= 0
|
||||||
|
sprite_y = PANEL_SPACING_EDGE
|
||||||
|
# Determine the relative positions of all option panels
|
||||||
|
sprite_pos = {}
|
||||||
|
@commands.keys.each do |key|
|
||||||
|
next if !@sprites[key] || !@sprites[key].visible # If Mystery Gift option isn't available
|
||||||
|
sprite_pos[key] = sprite_y
|
||||||
|
sprite_y += @sprites[key].height + PANEL_SPACING
|
||||||
|
end
|
||||||
|
# Determine an offset that ensures the selected option panel is on-screen
|
||||||
|
screen_y = sprite_pos[@index] - @panel_y_offset
|
||||||
|
if screen_y < PANEL_SPACING_EDGE
|
||||||
|
@panel_y_offset = sprite_pos[@index] - PANEL_SPACING_EDGE
|
||||||
|
elsif screen_y + @sprites[@index].height > Graphics.height - PANEL_SPACING_EDGE
|
||||||
|
@panel_y_offset = sprite_pos[@index] + @sprites[@index].height + PANEL_SPACING_EDGE - Graphics.height
|
||||||
|
end
|
||||||
|
# Apply the calculated positions to all option panels
|
||||||
|
sprite_pos.each_pair do |key, value|
|
||||||
|
@sprites[key].y = value - @panel_y_offset
|
||||||
|
end
|
||||||
|
@sprites[:continue_previous]&.y = @sprites[:continue].y
|
||||||
|
@sprites[:continue_next]&.y = @sprites[:continue].y
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_selected_panel
|
||||||
|
@commands.keys.each do |key|
|
||||||
|
@sprites[key]&.selected = (key == @index)
|
||||||
|
end
|
||||||
|
@sprites[:continue_previous]&.selected = false
|
||||||
|
@sprites[:continue_next]&.selected = false
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_on_index_changed(old_index)
|
||||||
|
refresh_selected_panel
|
||||||
|
refresh_panel_positions
|
||||||
|
end
|
||||||
|
|
||||||
|
def refresh_after_save_file_deleted
|
||||||
|
@slot_index = [@slot_index, @save_data.length - 1].min
|
||||||
|
if @save_data.empty?
|
||||||
|
[:continue, :continue_previous, :continue_next].each do |key|
|
||||||
|
@sprites[key].dispose if @sprites[key] && !@sprites[key].disposed?
|
||||||
|
@sprites[key] = nil
|
||||||
|
end
|
||||||
|
@sprites[:mystery_gift].visible = false
|
||||||
|
go_to_next_option(false)
|
||||||
|
else
|
||||||
|
if @save_data.length == 1
|
||||||
|
[:continue_previous, :continue_next].each do |key|
|
||||||
|
@sprites[key].dispose if @sprites[key] && !@sprites[key].disposed?
|
||||||
|
@sprites[key] = nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
set_slot_index(@slot_index, true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def update_input
|
||||||
|
# Check for movement to a new option
|
||||||
|
if Input.repeat?(Input::UP)
|
||||||
|
go_to_previous_option
|
||||||
|
elsif Input.repeat?(Input::DOWN)
|
||||||
|
go_to_next_option
|
||||||
|
end
|
||||||
|
# Check for movement to a different save slot
|
||||||
|
if @index == :continue && @save_data.length > 1
|
||||||
|
if Input.repeat?(Input::LEFT)
|
||||||
|
go_to_previous_save_slot
|
||||||
|
elsif Input.repeat?(Input::RIGHT)
|
||||||
|
go_to_next_save_slot
|
||||||
|
end
|
||||||
|
end
|
||||||
|
# Check for interaction
|
||||||
|
if Input.trigger?(Input::USE)
|
||||||
|
if @index == :continue && Input.press?(Input::ACTION) && Input.press?(Input::BACK)
|
||||||
|
pbPlayDecisionSE
|
||||||
|
return :delete_save
|
||||||
|
end
|
||||||
|
return update_interaction(Input::USE)
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_interaction(input)
|
||||||
|
case input
|
||||||
|
when Input::USE
|
||||||
|
pbPlayDecisionSE if @index != :quit_game
|
||||||
|
return @index # This is a key from @commands
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
#
|
||||||
|
#===============================================================================
|
||||||
|
class UI::Load < UI::BaseScreen
|
||||||
|
attr_reader :save_data
|
||||||
|
|
||||||
|
SCREEN_ID = :load_screen
|
||||||
|
|
||||||
|
def initialize
|
||||||
|
load_save_data
|
||||||
|
if $DEBUG && !FileTest.exist?("Game.rgssad") && Settings::SKIP_CONTINUE_SCREEN
|
||||||
|
@disposed = true
|
||||||
|
perform_action((@save_data.empty?) ? :new_game : :continue)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
set_commands
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def initialize_visuals
|
||||||
|
@visuals = UI::LoadVisuals.new(@commands, @save_data, @default_slot_index)
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def slot_index
|
||||||
|
return @visuals&.slot_index || @default_slot_index
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_commands
|
||||||
|
@commands = {}
|
||||||
|
MenuHandlers.each_available(:load_screen, self) do |option, _hash, name|
|
||||||
|
@commands[option] = name
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def load_save_data
|
||||||
|
@save_data = []
|
||||||
|
@default_slot_index = 0
|
||||||
|
last_edited_time = nil
|
||||||
|
files = SaveData.all_save_files
|
||||||
|
files.each do |file|
|
||||||
|
# Load the save file
|
||||||
|
this_save_data = SaveData.read_from_file(SaveData::DIRECTORY + file)
|
||||||
|
if !SaveData.valid?(this_save_data)
|
||||||
|
if File.file?(SaveData::DIRECTORY + file + ".bak")
|
||||||
|
show_message(_INTL("The save file is corrupt. A backup will be loaded."))
|
||||||
|
this_save_data = load_save_file(SaveData::FILE_PATH + ".bak")
|
||||||
|
else
|
||||||
|
prompt_corrupted_save_deletion(file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@save_data.push([file, this_save_data])
|
||||||
|
# Find the most recently edited save file; default to selecting that one
|
||||||
|
save_time = this_save_data[:stats].real_time_saved || 0
|
||||||
|
if !last_edited_time || save_time > last_edited_time
|
||||||
|
last_edited_time = save_time
|
||||||
|
@default_slot_index = @save_data.length - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
SaveData.load_bootup_values(@save_data[@default_slot_index][1], true) if !@save_data.empty?
|
||||||
|
end
|
||||||
|
|
||||||
|
def prompt_corrupted_save_deletion(filename)
|
||||||
|
show_message(_INTL("The save file is corrupt, or is incompatible with this game.") + "\1")
|
||||||
|
pbPlayDecisionSE
|
||||||
|
exit if !show_confirm_serious_message(_INTL("Do you want to delete the save file and start anew?"))
|
||||||
|
delete_save_data(filename)
|
||||||
|
$PokemonSystem = PokemonSystem.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def prompt_save_deletion(filename)
|
||||||
|
if show_confirm_serious_message(_INTL("Delete this save file?"))
|
||||||
|
show_message(_INTL("Once a save file has been deleted, there is no way to recover it.") + "\1")
|
||||||
|
pbPlayDecisionSE
|
||||||
|
if show_confirm_serious_message(_INTL("Delete the save file anyway?"))
|
||||||
|
delete_save_data(filename) {
|
||||||
|
@save_data.delete_if { |save| save[0] == filename }
|
||||||
|
@visuals.refresh_after_save_file_deleted
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_save_data(filename)
|
||||||
|
begin
|
||||||
|
SaveData.delete_file(filename)
|
||||||
|
yield if block_given?
|
||||||
|
show_message(_INTL("The save file was deleted."))
|
||||||
|
rescue SystemCallError
|
||||||
|
show_message(_INTL("The save file could not be deleted."))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def full_refresh
|
||||||
|
@visuals.full_refresh
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
# Actions that can be triggered in the load screen.
|
||||||
|
#===============================================================================
|
||||||
|
UIActionHandlers.add(UI::Load::SCREEN_ID, :continue, {
|
||||||
|
:effect => proc { |screen|
|
||||||
|
screen.end_screen
|
||||||
|
Game.load(screen.save_data[screen.slot_index][1])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
UIActionHandlers.add(UI::Load::SCREEN_ID, :mystery_gift, {
|
||||||
|
:effect => proc { |screen|
|
||||||
|
pbFadeOutInWithUpdate(screen.sprites) do
|
||||||
|
pbDownloadMysteryGift(screen.save_data[screen.slot_index][1][:player])
|
||||||
|
end
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
UIActionHandlers.add(UI::Load::SCREEN_ID, :new_game, {
|
||||||
|
:effect => proc { |screen|
|
||||||
|
screen.end_screen
|
||||||
|
Game.start_new
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
UIActionHandlers.add(UI::Load::SCREEN_ID, :options, {
|
||||||
|
:effect => proc { |screen|
|
||||||
|
pbFadeOutInWithUpdate(screen.sprites) do
|
||||||
|
options_scene = PokemonOption_Scene.new
|
||||||
|
options_screen = PokemonOptionScreen.new(options_scene)
|
||||||
|
options_screen.pbStartScreen(true)
|
||||||
|
screen.full_refresh
|
||||||
|
end
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
UIActionHandlers.add(UI::Load::SCREEN_ID, :language, {
|
||||||
|
:effect => proc { |screen|
|
||||||
|
screen.end_screen
|
||||||
|
$PokemonSystem.language = pbChooseLanguage
|
||||||
|
MessageTypes.load_message_files(Settings::LANGUAGES[$PokemonSystem.language][1])
|
||||||
|
if screen.save_data[screen.slot_index]
|
||||||
|
screen.save_data[screen.slot_index][1][:pokemon_system] = $PokemonSystem
|
||||||
|
File.open(SaveData::DIRECTORY + screen.save_data[screen.slot_index][0], "wb") do |file|
|
||||||
|
Marshal.dump(screen.save_data[screen.slot_index][1], file)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$scene = pbCallTitle
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
UIActionHandlers.add(UI::Load::SCREEN_ID, :debug, {
|
||||||
|
:effect => proc { |screen|
|
||||||
|
pbFadeOutInWithUpdate(screen.sprites) do
|
||||||
|
pbDebugMenu(false)
|
||||||
|
end
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
UIActionHandlers.add(UI::Load::SCREEN_ID, :quit_game, {
|
||||||
|
:effect => proc { |screen|
|
||||||
|
pbPlayCloseMenuSE
|
||||||
|
screen.end_screen
|
||||||
|
$scene = nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
UIActionHandlers.add(UI::Load::SCREEN_ID, :delete_save, {
|
||||||
|
:effect => proc { |screen|
|
||||||
|
screen.prompt_save_deletion(screen.save_data[screen.slot_index][0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
#===============================================================================
|
||||||
|
# Menu options that exist in the load screen.
|
||||||
|
#===============================================================================
|
||||||
|
MenuHandlers.add(:load_screen, :continue, {
|
||||||
|
"name" => _INTL("Continue"),
|
||||||
|
"order" => 10,
|
||||||
|
"condition" => proc { |screen| next screen.save_data && !screen.save_data.empty? }
|
||||||
|
})
|
||||||
|
|
||||||
|
# NOTE: Mystery Gift is always added as an option here, even if no save files
|
||||||
|
# have unlocked it. Whether it is shown depends on the selected save file,
|
||||||
|
# and its visibility is toggled elsewhere because of that.
|
||||||
|
MenuHandlers.add(:load_screen, :mystery_gift, {
|
||||||
|
"name" => _INTL("Mystery Gift"),
|
||||||
|
"order" => 20,
|
||||||
|
"condition" => proc { |screen| next screen.save_data && !screen.save_data.empty? }
|
||||||
|
})
|
||||||
|
|
||||||
|
MenuHandlers.add(:load_screen, :new_game, {
|
||||||
|
"name" => _INTL("New Game"),
|
||||||
|
"order" => 30
|
||||||
|
})
|
||||||
|
|
||||||
|
MenuHandlers.add(:load_screen, :options, {
|
||||||
|
"name" => _INTL("Options"),
|
||||||
|
"order" => 40
|
||||||
|
})
|
||||||
|
|
||||||
|
# TODO: Put language in the options screen?
|
||||||
|
MenuHandlers.add(:load_screen, :language, {
|
||||||
|
"name" => _INTL("Language"),
|
||||||
|
"order" => 50,
|
||||||
|
"condition" => proc { |screen| next Settings::LANGUAGES.length >= 2 }
|
||||||
|
})
|
||||||
|
|
||||||
|
MenuHandlers.add(:load_screen, :debug, {
|
||||||
|
"name" => _INTL("Debug"),
|
||||||
|
"order" => 60,
|
||||||
|
"condition" => proc { |screen| next $DEBUG }
|
||||||
|
})
|
||||||
|
|
||||||
|
MenuHandlers.add(:load_screen, :quit_game, {
|
||||||
|
"name" => _INTL("Quit Game"),
|
||||||
|
"order" => 9999
|
||||||
|
})
|
||||||
@@ -701,7 +701,6 @@ class UI::PokemonStorageVisuals < UI::BaseVisuals
|
|||||||
# 0+ = box number
|
# 0+ = box number
|
||||||
attr_reader :box
|
attr_reader :box
|
||||||
attr_reader :sub_mode
|
attr_reader :sub_mode
|
||||||
attr_reader :sprites
|
|
||||||
|
|
||||||
GRAPHICS_FOLDER = "Storage/" # Subfolder in Graphics/UI
|
GRAPHICS_FOLDER = "Storage/" # Subfolder in Graphics/UI
|
||||||
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
|
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
|
||||||
@@ -1352,9 +1351,9 @@ class UI::PokemonStorageVisuals < UI::BaseVisuals
|
|||||||
return update_interaction(Input::BACK)
|
return update_interaction(Input::BACK)
|
||||||
elsif Input.trigger?(Input::ACTION)
|
elsif Input.trigger?(Input::ACTION)
|
||||||
return update_interaction(Input::ACTION)
|
return update_interaction(Input::ACTION)
|
||||||
elsif Input.trigger?(Input::JUMPUP)
|
elsif Input.repeat?(Input::JUMPUP)
|
||||||
return update_interaction(Input::JUMPUP)
|
return update_interaction(Input::JUMPUP)
|
||||||
elsif Input.trigger?(Input::JUMPDOWN)
|
elsif Input.repeat?(Input::JUMPDOWN)
|
||||||
return update_interaction(Input::JUMPDOWN)
|
return update_interaction(Input::JUMPDOWN)
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -125,7 +125,6 @@ end
|
|||||||
#
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class UI::MartVisuals < UI::BaseVisuals
|
class UI::MartVisuals < UI::BaseVisuals
|
||||||
attr_reader :sprites
|
|
||||||
attr_reader :pocket
|
attr_reader :pocket
|
||||||
|
|
||||||
GRAPHICS_FOLDER = "Mart/" # Subfolder in Graphics/UI
|
GRAPHICS_FOLDER = "Mart/" # Subfolder in Graphics/UI
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
=begin
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
#
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
@@ -356,3 +357,4 @@ class PokemonLoadScreen
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
=end
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
=begin
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
# Pokémon icons.
|
# Pokémon icons.
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
@@ -2029,3 +2030,4 @@ class PokemonStorageScreen
|
|||||||
return retval
|
return retval
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
=end
|
||||||
|
|||||||
@@ -4,9 +4,7 @@
|
|||||||
class Scene_DebugIntro
|
class Scene_DebugIntro
|
||||||
def main
|
def main
|
||||||
Graphics.transition(0)
|
Graphics.transition(0)
|
||||||
sscene = PokemonLoad_Scene.new
|
UI::Load.new.main
|
||||||
sscreen = PokemonLoadScreen.new(sscene)
|
|
||||||
sscreen.pbStartLoadScreen
|
|
||||||
Graphics.freeze
|
Graphics.freeze
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user