mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-06 06:01:46 +00:00
Save data rewrite & Game module (#91)
This commit is contained in:
@@ -5,6 +5,9 @@
|
|||||||
#==============================================================================#
|
#==============================================================================#
|
||||||
|
|
||||||
module Settings
|
module Settings
|
||||||
|
# The version of the game. It has to adhere to the MAJOR.MINOR.PATCH format.
|
||||||
|
GAME_VERSION = '1.0.0'
|
||||||
|
|
||||||
# The generation that the battle system follows. Used throughout the battle
|
# The generation that the battle system follows. Used throughout the battle
|
||||||
# scripts, and also by some other settings which are used in and out of battle
|
# scripts, and also by some other settings which are used in and out of battle
|
||||||
# (you can of course change those settings to suit your game).
|
# (you can of course change those settings to suit your game).
|
||||||
|
|||||||
@@ -2,13 +2,13 @@
|
|||||||
module Kernel
|
module Kernel
|
||||||
private
|
private
|
||||||
|
|
||||||
# Used to check whether values are of a given class or respond to a method.
|
# Used to check whether method arguments are of a given class or respond to a method.
|
||||||
# @param value_pairs [Hash{Object => Class, Array<Class>, Symbol}] value pairs to validate
|
# @param value_pairs [Hash{Object => Class, Array<Class>, Symbol}] value pairs to validate
|
||||||
# @example Validate a class or method
|
# @example Validate a class or method
|
||||||
# validate foo => Integer, baz => :to_s # raises an error if foo is not an Integer or if baz doesn't implement #to_s
|
# validate foo => Integer, baz => :to_s # raises an error if foo is not an Integer or if baz doesn't implement #to_s
|
||||||
# @example Validate a class from an array
|
# @example Validate a class from an array
|
||||||
# validate foo => [Sprite, Bitmap, Viewport] # raises an error if foo isn't a Sprite, Bitmap or Viewport
|
# validate foo => [Sprite, Bitmap, Viewport] # raises an error if foo isn't a Sprite, Bitmap or Viewport
|
||||||
# @raise [ArgumentError] raised if validation fails
|
# @raise [ArgumentError] if validation fails
|
||||||
def validate(value_pairs)
|
def validate(value_pairs)
|
||||||
unless value_pairs.is_a?(Hash)
|
unless value_pairs.is_a?(Hash)
|
||||||
raise ArgumentError, "Non-hash argument #{value_pairs.inspect} passed into validate."
|
raise ArgumentError, "Non-hash argument #{value_pairs.inspect} passed into validate."
|
||||||
|
|||||||
106
Data/Scripts/007_Events and files/001_Save data/001_SaveData.rb
Normal file
106
Data/Scripts/007_Events and files/001_Save data/001_SaveData.rb
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# The SaveData module is used to manipulate save data. It contains the {Value}s
|
||||||
|
# that make up the save data and {Conversion}s for resolving incompatibilities
|
||||||
|
# between Essentials and game versions.
|
||||||
|
# @see SaveData.register
|
||||||
|
# @see SaveData.register_conversion
|
||||||
|
module SaveData
|
||||||
|
# Contains the file path of the save file.
|
||||||
|
FILE_PATH = if File.directory?(System.data_directory)
|
||||||
|
System.data_directory + '/Game.rxdata'
|
||||||
|
else
|
||||||
|
'./Game.rxdata'
|
||||||
|
end
|
||||||
|
|
||||||
|
# Compiles the save data and saves a marshaled version of it into
|
||||||
|
# the given file.
|
||||||
|
# @param file_path [String] path of the file to save into
|
||||||
|
# @raise [InvalidValueError] if an invalid value is being saved
|
||||||
|
def self.save_to_file(file_path)
|
||||||
|
validate file_path => String
|
||||||
|
|
||||||
|
save_data = self.compile
|
||||||
|
|
||||||
|
File.open(file_path, 'wb') { |file| Marshal.dump(save_data, file) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fetches save data from the given file.
|
||||||
|
# @param file_path [String] path of the file to read from
|
||||||
|
# @return [Hash] save data in Hash format
|
||||||
|
# @raise (see .get_data_from_file)
|
||||||
|
def self.read_from_file(file_path)
|
||||||
|
validate file_path => String
|
||||||
|
|
||||||
|
save_data = get_data_from_file(file_path)
|
||||||
|
|
||||||
|
save_data = to_hash_format(save_data) if save_data.is_a?(Array)
|
||||||
|
|
||||||
|
return save_data
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether the save file exists
|
||||||
|
def self.exists?
|
||||||
|
return File.file?(FILE_PATH)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Deletes the save file (and a possible .bak backup file if one exists)
|
||||||
|
# @raise [Error::ENOENT]
|
||||||
|
def self.delete_file
|
||||||
|
File.delete(FILE_PATH)
|
||||||
|
File.delete(FILE_PATH + '.bak') if File.file?(FILE_PATH + '.bak')
|
||||||
|
end
|
||||||
|
|
||||||
|
# Fetches the save data from the given file.
|
||||||
|
# Returns an Array in the case of a pre-v19 save file.
|
||||||
|
# @param file_path [String] path of the file to load from
|
||||||
|
# @return [Hash, Array] loaded save data
|
||||||
|
# @raise [IOError, SystemCallError] if file opening fails
|
||||||
|
def self.get_data_from_file(file_path)
|
||||||
|
validate file_path => String
|
||||||
|
save_data = nil
|
||||||
|
|
||||||
|
File.open(file_path) do |file|
|
||||||
|
data = Marshal.load(file)
|
||||||
|
|
||||||
|
if data.is_a?(Hash)
|
||||||
|
save_data = data
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
|
save_data = [data]
|
||||||
|
|
||||||
|
save_data << Marshal.load(file) until file.eof?
|
||||||
|
end
|
||||||
|
|
||||||
|
return save_data
|
||||||
|
end
|
||||||
|
|
||||||
|
# Converts the pre-v19 format data to the new format.
|
||||||
|
# @param old_format [Array] pre-v19 format save data
|
||||||
|
# @return [Hash] save data in new format
|
||||||
|
def self.to_hash_format(old_format)
|
||||||
|
validate old_format => Array
|
||||||
|
hash = {}
|
||||||
|
|
||||||
|
@values.each do |value|
|
||||||
|
data = value.get_from_old_format(old_format)
|
||||||
|
hash[value.id] = data unless data.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
return hash
|
||||||
|
end
|
||||||
|
|
||||||
|
# Moves a save file from the old Saved Games folder to the new
|
||||||
|
# location specified by {FILE_PATH}. Does nothing if a save file
|
||||||
|
# already exists in {FILE_PATH}.
|
||||||
|
def self.move_old_windows_save
|
||||||
|
return if File.file?(FILE_PATH)
|
||||||
|
game_title = System.game_title.gsub(/[^\w ]/, '_')
|
||||||
|
home = ENV['HOME'] || ENV['HOMEPATH']
|
||||||
|
return if home.nil?
|
||||||
|
old_location = File.join(home, 'Saved Games', game_title)
|
||||||
|
return unless File.directory?(old_location)
|
||||||
|
old_file = File.join(old_location, 'Game.rxdata')
|
||||||
|
return unless File.file?(old_file)
|
||||||
|
File.move(old_file, FILE_PATH)
|
||||||
|
end
|
||||||
|
end
|
||||||
264
Data/Scripts/007_Events and files/001_Save data/002_Values.rb
Normal file
264
Data/Scripts/007_Events and files/001_Save data/002_Values.rb
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
module SaveData
|
||||||
|
# Contains Value objects for each save element.
|
||||||
|
# Populated during runtime by SaveData.register calls.
|
||||||
|
# @type [Array<Value>]
|
||||||
|
@values = []
|
||||||
|
|
||||||
|
# An error raised if an invalid save value is being saved or loaded.
|
||||||
|
class InvalidValueError < RuntimeError; end
|
||||||
|
|
||||||
|
# Represents a single value in save data.
|
||||||
|
# New values are added using {SaveData.register}.
|
||||||
|
class Value
|
||||||
|
# @return [Symbol] the value id
|
||||||
|
attr_reader :id
|
||||||
|
|
||||||
|
# @param id [Symbol] value id
|
||||||
|
def initialize(id, &block)
|
||||||
|
validate id => Symbol, block => Proc
|
||||||
|
@id = id
|
||||||
|
@loaded = false
|
||||||
|
@load_in_bootup = false
|
||||||
|
instance_eval(&block)
|
||||||
|
raise "No save_value defined for save value #{id.inspect}" if @save_proc.nil?
|
||||||
|
raise "No load_value defined for save value #{id.inspect}" if @load_proc.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
# Calls the value's save proc and returns its value.
|
||||||
|
# @return [Object] save proc value
|
||||||
|
# @raise [InvalidValueError] if an invalid value is being saved
|
||||||
|
def save
|
||||||
|
value = @save_proc.call
|
||||||
|
|
||||||
|
validate_value(value)
|
||||||
|
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
|
||||||
|
# Calls the value's load proc with the given argument passed into it.
|
||||||
|
# @param value [Object] load proc argument
|
||||||
|
# @raise [InvalidValueError] if an invalid value is being loaded
|
||||||
|
def load(value)
|
||||||
|
validate_value(value)
|
||||||
|
|
||||||
|
@load_proc.call(value)
|
||||||
|
@loaded = true
|
||||||
|
end
|
||||||
|
|
||||||
|
# @param value [Object] value to check
|
||||||
|
# @return [Boolean] whether the given value is valid
|
||||||
|
def valid?(value)
|
||||||
|
return true if @ensured_class.nil?
|
||||||
|
return value.is_a?(Object.const_get(@ensured_class))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Calls the save value's load proc with the value fetched
|
||||||
|
# from the defined new game value proc.
|
||||||
|
# @raise (see #load)
|
||||||
|
def load_new_game_value
|
||||||
|
unless self.has_new_game_proc?
|
||||||
|
raise "Save value #{@id.inspect} has no new_game_value defined"
|
||||||
|
end
|
||||||
|
|
||||||
|
self.load(@new_game_value_proc.call)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether the value has a new game value proc defined
|
||||||
|
def has_new_game_proc?
|
||||||
|
return @new_game_value_proc.is_a?(Proc)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether the value should be loaded during bootup
|
||||||
|
def load_in_bootup?
|
||||||
|
return @load_in_bootup
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Boolean] whether the value has been loaded
|
||||||
|
def loaded?
|
||||||
|
return @loaded
|
||||||
|
end
|
||||||
|
|
||||||
|
# Uses the {#from_old_format} proc to select the correct data from
|
||||||
|
# +old_format+ and return it.
|
||||||
|
# Returns nil if the proc is undefined.
|
||||||
|
# @param old_format [Array] old format to load value from
|
||||||
|
# @return [Object] data from the old format
|
||||||
|
def get_from_old_format(old_format)
|
||||||
|
return nil if @old_format_get_proc.nil?
|
||||||
|
return @old_format_get_proc.call(old_format)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# @!group Configuration
|
||||||
|
|
||||||
|
# Defines what is saved into save data. Requires a block.
|
||||||
|
# @see SaveData.register
|
||||||
|
def save_value(&block)
|
||||||
|
raise ArgumentError, 'No block given to save_value' unless block_given?
|
||||||
|
@save_proc = block
|
||||||
|
end
|
||||||
|
|
||||||
|
# Defines how the loaded value is placed into a global variable.
|
||||||
|
# Requires a block with the loaded value as its parameter.
|
||||||
|
# @see SaveData.register
|
||||||
|
def load_value(&block)
|
||||||
|
raise ArgumentError, 'No block given to load_value' unless block_given?
|
||||||
|
@load_proc = block
|
||||||
|
end
|
||||||
|
|
||||||
|
# If present, sets the value to be loaded during bootup.
|
||||||
|
# @see SaveData.register
|
||||||
|
def load_in_bootup
|
||||||
|
@load_in_bootup = true
|
||||||
|
end
|
||||||
|
|
||||||
|
# If present, defines what the value is set to at the start of a new game.
|
||||||
|
# @see SaveData.register
|
||||||
|
def new_game_value(&block)
|
||||||
|
raise ArgumentError, 'No block given to new_game_value' unless block_given?
|
||||||
|
@new_game_value_proc = block
|
||||||
|
end
|
||||||
|
|
||||||
|
# If present, ensures that the value is of the given class.
|
||||||
|
# @param class_name [Symbol] class to enforce
|
||||||
|
# @see SaveData.register
|
||||||
|
def ensure_class(class_name)
|
||||||
|
validate class_name => Symbol
|
||||||
|
@ensured_class = class_name
|
||||||
|
end
|
||||||
|
|
||||||
|
# If present, defines how the value should be fetched from the pre-v19
|
||||||
|
# save format. Requires a block with the old format array as its parameter.
|
||||||
|
# @see SaveData.register
|
||||||
|
def from_old_format(&block)
|
||||||
|
raise ArgumentError, 'No block given to from_old_format' unless block_given?
|
||||||
|
@old_format_get_proc = block
|
||||||
|
end
|
||||||
|
|
||||||
|
# @!endgroup
|
||||||
|
|
||||||
|
# Raises an {InvalidValueError} if the given value is invalid.
|
||||||
|
# @param value [Object] value to check
|
||||||
|
# @raise [InvalidValueError] if the value is invalid
|
||||||
|
def validate_value(value)
|
||||||
|
return if self.valid?(value)
|
||||||
|
|
||||||
|
raise InvalidValueError,
|
||||||
|
"Save value #{@id.inspect} is not a #{@ensured_class} (#{value.class.name} given)"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Registers a {Value} to be saved into save data.
|
||||||
|
# Takes a block which defines the value's saving ({Value#save_value})
|
||||||
|
# and loading ({Value#load_value}) procedures.
|
||||||
|
#
|
||||||
|
# It is also possible to provide a proc for fetching the value
|
||||||
|
# from the pre-v19 format ({Value#from_old_format}), define
|
||||||
|
# a value to be set upon starting a new game with {Value#new_game_value}
|
||||||
|
# and ensure that the saved and loaded value is of the correct
|
||||||
|
# class with {Value#ensure_class}.
|
||||||
|
#
|
||||||
|
# Values can be registered to be loaded on bootup with
|
||||||
|
# {Value#load_in_bootup}. If a new_game_value proc is defined, it
|
||||||
|
# will be called when the game is launched for the first time,
|
||||||
|
# or if the save data does not contain the value in question.
|
||||||
|
#
|
||||||
|
# @example Registering a new value
|
||||||
|
# SaveData.register(:foo) do
|
||||||
|
# ensure_class :Foo
|
||||||
|
# save_value { $foo }
|
||||||
|
# load_value { |value| $foo = value }
|
||||||
|
# new_game_value { Foo.new }
|
||||||
|
# from_old_format { |old_format| old_format[16] if old_format[16].is_a?(Foo) }
|
||||||
|
# end
|
||||||
|
# @example Registering a value to be loaded on bootup
|
||||||
|
# SaveData.register(:bar) do
|
||||||
|
# load_in_bootup
|
||||||
|
# save_value { $bar }
|
||||||
|
# load_value { |value| $bar = value }
|
||||||
|
# new_game_value { Bar.new }
|
||||||
|
# end
|
||||||
|
# @param id [Symbol] value id
|
||||||
|
# @yieldself [Value]
|
||||||
|
def self.register(id, &block)
|
||||||
|
validate id => Symbol
|
||||||
|
|
||||||
|
unless block_given?
|
||||||
|
raise ArgumentError, 'No block given to SaveData.register'
|
||||||
|
end
|
||||||
|
|
||||||
|
@values << Value.new(id, &block)
|
||||||
|
end
|
||||||
|
|
||||||
|
# @param save_data [Hash] save data to validate
|
||||||
|
# @return [Boolean] whether the given save data is valid
|
||||||
|
def self.valid?(save_data)
|
||||||
|
validate save_data => Hash
|
||||||
|
return @values.all? { |value| value.valid?(save_data[value.id]) }
|
||||||
|
end
|
||||||
|
|
||||||
|
# @return [Hash{Symbol => Object}] a hash representation of the save data
|
||||||
|
# @raise [InvalidValueError] if an invalid value is being saved
|
||||||
|
def self.compile
|
||||||
|
save_data = {}
|
||||||
|
@values.each { |value| save_data[value.id] = value.save }
|
||||||
|
return save_data
|
||||||
|
end
|
||||||
|
|
||||||
|
# Loads the values from the given save data by
|
||||||
|
# calling each {Value} object's {Value#load_value} proc.
|
||||||
|
# Values that are already loaded are skipped.
|
||||||
|
# If a value does not exist in the save data and has
|
||||||
|
# a {Value#new_game_value} proc defined, that value
|
||||||
|
# is loaded instead.
|
||||||
|
# @param save_data [Hash] save data to load
|
||||||
|
# @raise [InvalidValueError] if an invalid value is being loaded
|
||||||
|
def self.load_all_values(save_data)
|
||||||
|
validate save_data => Hash
|
||||||
|
|
||||||
|
load_values(save_data) { |value| !value.loaded? }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Loads each value from the given save data that has
|
||||||
|
# been set to be loaded during bootup.
|
||||||
|
# @param save_data [Hash] save data to load
|
||||||
|
# @raise [InvalidValueError] if an invalid value is being loaded
|
||||||
|
def self.load_bootup_values(save_data)
|
||||||
|
validate save_data => Hash
|
||||||
|
|
||||||
|
load_values(save_data) { |value| !value.loaded? && value.load_in_bootup? }
|
||||||
|
end
|
||||||
|
|
||||||
|
# Loads values from the given save data.
|
||||||
|
# An optional condition can be passed.
|
||||||
|
# @param save_data [Hash] save data to load from
|
||||||
|
# @param condition_block [Proc] optional condition
|
||||||
|
# @api private
|
||||||
|
def self.load_values(save_data, &condition_block)
|
||||||
|
@values.each do |value|
|
||||||
|
next if block_given? && !condition_block.call(value)
|
||||||
|
if save_data.has_key?(value.id)
|
||||||
|
value.load(save_data[value.id])
|
||||||
|
elsif value.has_new_game_proc?
|
||||||
|
value.load_new_game_value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Loads each {Value}'s new game value, if one is defined.
|
||||||
|
def self.load_new_game_values
|
||||||
|
@values.each do |value|
|
||||||
|
value.load_new_game_value if value.has_new_game_proc? && !value.loaded?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Goes through each value with {Value#load_in_bootup} enabled and
|
||||||
|
# loads their new game value, if one is defined.
|
||||||
|
def self.initialize_bootup_values
|
||||||
|
@values.each do |value|
|
||||||
|
next unless value.load_in_bootup?
|
||||||
|
value.load_new_game_value if value.has_new_game_proc? && !value.loaded?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,129 @@
|
|||||||
|
# Contains the save values defined in Essentials by default.
|
||||||
|
|
||||||
|
SaveData.register(:player) do
|
||||||
|
ensure_class :PlayerTrainer
|
||||||
|
save_value { $Trainer }
|
||||||
|
load_value { |value| $Trainer = value }
|
||||||
|
from_old_format { |old_format| old_format[0] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:frame_count) do
|
||||||
|
ensure_class :Integer
|
||||||
|
save_value { Graphics.frame_count }
|
||||||
|
load_value { |value| Graphics.frame_count = value }
|
||||||
|
new_game_value { 0 }
|
||||||
|
from_old_format { |old_format| old_format[1] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:game_system) do
|
||||||
|
load_in_bootup
|
||||||
|
ensure_class :Game_System
|
||||||
|
save_value { $game_system }
|
||||||
|
load_value { |value| $game_system = value }
|
||||||
|
new_game_value { Game_System.new }
|
||||||
|
from_old_format { |old_format| old_format[2] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:pokemon_system) do
|
||||||
|
load_in_bootup
|
||||||
|
ensure_class :PokemonSystem
|
||||||
|
save_value { $PokemonSystem }
|
||||||
|
load_value { |value| $PokemonSystem = value }
|
||||||
|
new_game_value { PokemonSystem.new }
|
||||||
|
from_old_format { |old_format| old_format[3] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:switches) do
|
||||||
|
ensure_class :Game_Switches
|
||||||
|
save_value { $game_switches }
|
||||||
|
load_value { |value| $game_switches = value }
|
||||||
|
new_game_value { Game_Switches.new }
|
||||||
|
from_old_format { |old_format| old_format[5] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:variables) do
|
||||||
|
ensure_class :Game_Variables
|
||||||
|
save_value { $game_variables }
|
||||||
|
load_value { |value| $game_variables = value }
|
||||||
|
new_game_value { Game_Variables.new }
|
||||||
|
from_old_format { |old_format| old_format[6] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:self_switches) do
|
||||||
|
ensure_class :Game_SelfSwitches
|
||||||
|
save_value { $game_self_switches }
|
||||||
|
load_value { |value| $game_self_switches = value }
|
||||||
|
new_game_value { Game_SelfSwitches.new }
|
||||||
|
from_old_format { |old_format| old_format[7] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:game_screen) do
|
||||||
|
ensure_class :Game_Screen
|
||||||
|
save_value { $game_screen }
|
||||||
|
load_value { |value| $game_screen = value }
|
||||||
|
new_game_value { Game_Screen.new }
|
||||||
|
from_old_format { |old_format| old_format[8] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:map_factory) do
|
||||||
|
ensure_class :PokemonMapFactory
|
||||||
|
save_value { $MapFactory }
|
||||||
|
load_value { |value| $MapFactory = value }
|
||||||
|
from_old_format { |old_format| old_format[9] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:game_player) do
|
||||||
|
ensure_class :Game_Player
|
||||||
|
save_value { $game_player }
|
||||||
|
load_value { |value| $game_player = value }
|
||||||
|
new_game_value { Game_Player.new }
|
||||||
|
from_old_format { |old_format| old_format[10] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:global_metadata) do
|
||||||
|
ensure_class :PokemonGlobalMetadata
|
||||||
|
save_value { $PokemonGlobal }
|
||||||
|
load_value { |value| $PokemonGlobal = value }
|
||||||
|
new_game_value { PokemonGlobalMetadata.new }
|
||||||
|
from_old_format { |old_format| old_format[11] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:map_metadata) do
|
||||||
|
ensure_class :PokemonMapMetadata
|
||||||
|
save_value { $PokemonMap }
|
||||||
|
load_value { |value| $PokemonMap = value }
|
||||||
|
new_game_value { PokemonMapMetadata.new }
|
||||||
|
from_old_format { |old_format| old_format[12] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:bag) do
|
||||||
|
ensure_class :PokemonBag
|
||||||
|
save_value { $PokemonBag }
|
||||||
|
load_value { |value| $PokemonBag = value }
|
||||||
|
from_old_format { |old_format| old_format[13] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:storage_system) do
|
||||||
|
ensure_class :PokemonStorage
|
||||||
|
save_value { $PokemonStorage }
|
||||||
|
load_value { |value| $PokemonStorage = value }
|
||||||
|
new_game_value { PokemonStorage.new }
|
||||||
|
from_old_format { |old_format| old_format[14] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:essentials_version) do
|
||||||
|
load_in_bootup
|
||||||
|
ensure_class :String
|
||||||
|
save_value { Essentials::VERSION }
|
||||||
|
load_value { |value| $SaveVersion = value }
|
||||||
|
new_game_value { Essentials::VERSION }
|
||||||
|
from_old_format { |old_format| old_format[15] }
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register(:game_version) do
|
||||||
|
load_in_bootup
|
||||||
|
ensure_class :String
|
||||||
|
save_value { Settings::GAME_VERSION }
|
||||||
|
load_value { |value| $game_version = value }
|
||||||
|
new_game_value { Settings::GAME_VERSION }
|
||||||
|
end
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
module SaveData
|
||||||
|
# Contains Conversion objects for each defined conversion:
|
||||||
|
# {
|
||||||
|
# :essentials => {
|
||||||
|
# '19' => [<Conversion>, ...],
|
||||||
|
# '19.1' => [<Conversion>, ...],
|
||||||
|
# ...
|
||||||
|
# },
|
||||||
|
# :game => {
|
||||||
|
# '1.1.0' => [<Conversion>, ...],
|
||||||
|
# '1.2.0' => [<Conversion>, ...],
|
||||||
|
# ...
|
||||||
|
# }
|
||||||
|
# }
|
||||||
|
# Populated during runtime by SaveData.register_conversion calls.
|
||||||
|
@conversions = {
|
||||||
|
essentials: {},
|
||||||
|
game: {}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Represents a conversion made to save data.
|
||||||
|
# New conversions are added using {SaveData.register_conversion}.
|
||||||
|
class Conversion
|
||||||
|
# @return [Symbol] conversion ID
|
||||||
|
attr_reader :id
|
||||||
|
# @return [String] conversion title
|
||||||
|
attr_reader :title
|
||||||
|
# @return [Symbol] trigger type of the conversion (+:essentials+ or +:game+)
|
||||||
|
attr_reader :trigger_type
|
||||||
|
# @return [String] trigger version of the conversion
|
||||||
|
attr_reader :version
|
||||||
|
|
||||||
|
# @param id [String] conversion ID
|
||||||
|
def initialize(id, &block)
|
||||||
|
@id = id
|
||||||
|
@value_procs = {}
|
||||||
|
@all_proc = nil
|
||||||
|
@title = "Running conversion #{@id}"
|
||||||
|
@trigger_type = nil
|
||||||
|
@version = nil
|
||||||
|
instance_eval(&block)
|
||||||
|
if @trigger_type.nil? || @version.nil?
|
||||||
|
raise "Conversion #{@id} is missing a condition"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Runs the conversion on the given save data.
|
||||||
|
# @param save_data [Hash]
|
||||||
|
def run(save_data)
|
||||||
|
@value_procs.each do |value_id, proc|
|
||||||
|
unless save_data.has_key?(value_id)
|
||||||
|
raise "Save data does not have value #{value_id.inspect}"
|
||||||
|
end
|
||||||
|
proc.call(save_data[value_id])
|
||||||
|
end
|
||||||
|
@all_proc.call(save_data) if @all_proc.is_a?(Proc)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Returns whether the conversion should be run with the given version.
|
||||||
|
# @param version [String] version to check
|
||||||
|
# @return [Boolean] whether the conversion should be run
|
||||||
|
def should_run?(version)
|
||||||
|
return PluginManager.compare_versions(version, @version) < 0
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# @!group Configuration
|
||||||
|
|
||||||
|
# Sets the conversion's title.
|
||||||
|
# @param new_title [String] conversion title
|
||||||
|
# @note Since conversions are run before loading the player's chosen language,
|
||||||
|
# conversion titles can not be localized.
|
||||||
|
# @see SaveData.register_conversion
|
||||||
|
def display_title(new_title)
|
||||||
|
validate new_title => String
|
||||||
|
@title = new_title
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sets the conversion to trigger for save files created below
|
||||||
|
# the given Essentials version.
|
||||||
|
# @param version [Numeric, String]
|
||||||
|
# @see SaveData.register_conversion
|
||||||
|
def essentials_version(version)
|
||||||
|
validate version => [Numeric, String]
|
||||||
|
|
||||||
|
raise "Multiple conditions in conversion #{@id}" unless @version.nil?
|
||||||
|
|
||||||
|
@trigger_type = :essentials
|
||||||
|
@version = version.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
# Sets the conversion to trigger for save files created below
|
||||||
|
# the given game version.
|
||||||
|
# @param version [Numeric, String]
|
||||||
|
# @see SaveData.register_conversion
|
||||||
|
def game_version(version)
|
||||||
|
validate version => [Numeric, String]
|
||||||
|
|
||||||
|
raise "Multiple conditions in conversion #{@id}" unless @version.nil?
|
||||||
|
|
||||||
|
@trigger_type = :game
|
||||||
|
@version = version.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
# Defines a conversion to the given save value.
|
||||||
|
# @param value_id [Symbol] save value ID
|
||||||
|
# @see SaveData.register_conversion
|
||||||
|
def to_value(value_id, &block)
|
||||||
|
validate value_id => Symbol
|
||||||
|
|
||||||
|
raise ArgumentError, 'No block given to to_value' unless block_given?
|
||||||
|
|
||||||
|
if @value_procs[value_id].is_a?(Proc)
|
||||||
|
raise "Multiple to_value definitions in conversion #{@id} for #{value_id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@value_procs[value_id] = block
|
||||||
|
end
|
||||||
|
|
||||||
|
# Defines a conversion to the entire save data.
|
||||||
|
# @see SaveData.register_conversion
|
||||||
|
def to_all(&block)
|
||||||
|
raise ArgumentError, 'No block given to to_all' unless block_given?
|
||||||
|
|
||||||
|
if @all_proc.is_a?(Proc)
|
||||||
|
raise "Multiple to_all definitions in conversion #{@id}"
|
||||||
|
end
|
||||||
|
|
||||||
|
@all_proc = block
|
||||||
|
end
|
||||||
|
|
||||||
|
# @!endgroup
|
||||||
|
end
|
||||||
|
|
||||||
|
# Registers a {Conversion} to occur for save data that meets the given criteria.
|
||||||
|
# Two types of criteria can be defined: {Conversion#essentials_version} and
|
||||||
|
# {Conversion#game_version}. The conversion is automatically run on save data
|
||||||
|
# that contains an older version number.
|
||||||
|
#
|
||||||
|
# A single value can be modified with {Conversion#to_value}. The entire save data
|
||||||
|
# is accessed with {Conversion#to_all}, and a conversion title can be specified
|
||||||
|
# with {Conversion#display_title}.
|
||||||
|
# @example Registering a new conversion
|
||||||
|
# SaveData.register_conversion(:my_conversion) do
|
||||||
|
# game_version '1.1.0'
|
||||||
|
# display_title 'Converting some stuff'
|
||||||
|
# to_value :player do |player|
|
||||||
|
# # code that modifies the :player value
|
||||||
|
# end
|
||||||
|
# to_all do |save_data|
|
||||||
|
# save_data[:new_value] = Foo.new
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
# @yieldself [Conversion]
|
||||||
|
def self.register_conversion(id, &block)
|
||||||
|
validate id => Symbol
|
||||||
|
|
||||||
|
unless block_given?
|
||||||
|
raise ArgumentError, 'No block given to SaveData.register_conversion'
|
||||||
|
end
|
||||||
|
|
||||||
|
conversion = Conversion.new(id, &block)
|
||||||
|
|
||||||
|
@conversions[conversion.trigger_type][conversion.version] ||= []
|
||||||
|
@conversions[conversion.trigger_type][conversion.version] << conversion
|
||||||
|
end
|
||||||
|
|
||||||
|
# Runs all possible conversions on the given save data.
|
||||||
|
# Saves a backup before running conversions.
|
||||||
|
# @param save_data [Hash] save data to run conversions on
|
||||||
|
# @return [Boolean] whether conversions were run
|
||||||
|
def self.run_conversions(save_data)
|
||||||
|
validate save_data => Hash
|
||||||
|
conversions_to_run = self.get_conversions(save_data)
|
||||||
|
|
||||||
|
return false if conversions_to_run.none?
|
||||||
|
|
||||||
|
File.open(SaveData::FILE_PATH + '.bak', 'wb') { |f| Marshal.dump(save_data, f) }
|
||||||
|
|
||||||
|
echoln "Running #{conversions_to_run.length} conversions..."
|
||||||
|
|
||||||
|
conversions_to_run.each do |conversion|
|
||||||
|
echo "#{conversion.title}..."
|
||||||
|
conversion.run(save_data)
|
||||||
|
echoln ' done.'
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
# @param save_data [Hash] save data to get conversions for
|
||||||
|
# @return [Array<Conversion>] all conversions that should be run on the data
|
||||||
|
def self.get_conversions(save_data)
|
||||||
|
conversions_to_run = []
|
||||||
|
|
||||||
|
versions = {
|
||||||
|
essentials: save_data[:essentials_version] || '18.1',
|
||||||
|
game: save_data[:game_version] || '0.0.0'
|
||||||
|
}
|
||||||
|
|
||||||
|
[:essentials, :game].each do |trigger_type|
|
||||||
|
# Ensure the versions are sorted from lowest to highest
|
||||||
|
sorted_versions = @conversions[trigger_type].keys.sort do |v1, v2|
|
||||||
|
PluginManager.compare_versions(v1, v2)
|
||||||
|
end
|
||||||
|
|
||||||
|
sorted_versions.each do |version|
|
||||||
|
@conversions[trigger_type][version].each do |conversion|
|
||||||
|
next unless conversion.should_run?(versions[trigger_type])
|
||||||
|
conversions_to_run << conversion
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return conversions_to_run
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
# Contains conversions defined in Essentials by default.
|
||||||
|
|
||||||
|
SaveData.register_conversion(:v19_define_versions) do
|
||||||
|
essentials_version 19
|
||||||
|
display_title 'Defining versions in save data'
|
||||||
|
to_all do |save_data|
|
||||||
|
unless save_data.has_key?(:essentials_version)
|
||||||
|
save_data[:essentials_version] = Essentials::VERSION
|
||||||
|
end
|
||||||
|
unless save_data.has_key?(:game_version)
|
||||||
|
save_data[:game_version] = Settings::GAME_VERSION
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register_conversion(:v19_convert_player) do
|
||||||
|
essentials_version 19
|
||||||
|
display_title 'Converting player trainer'
|
||||||
|
to_all do |save_data|
|
||||||
|
next if save_data[:player].is_a?(PlayerTrainer)
|
||||||
|
# Conversion of the party is handled in PokeBattle_Trainer.copy
|
||||||
|
save_data[:player] = PokeBattle_Trainer.copy(save_data[:player])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register_conversion(:v19_convert_storage) do
|
||||||
|
essentials_version 19
|
||||||
|
display_title 'Converting Pokémon in storage'
|
||||||
|
to_value :storage_system do |storage|
|
||||||
|
storage.instance_eval do
|
||||||
|
for box in 0...self.maxBoxes
|
||||||
|
for i in 0...self.maxPokemon(box)
|
||||||
|
next unless self[box, i]
|
||||||
|
next if self[box, i].is_a?(Pokemon)
|
||||||
|
self[box, i] = PokeBattle_Pokemon.copy(self[box, i])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end # storage.instance_eval
|
||||||
|
end # to_value
|
||||||
|
end
|
||||||
|
|
||||||
|
SaveData.register_conversion(:v19_convert_global_metadata) do
|
||||||
|
essentials_version 19
|
||||||
|
display_title 'Converting global metadata'
|
||||||
|
to_value :global_metadata do |global|
|
||||||
|
global.encounter_version ||= 0
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -51,7 +51,7 @@ class PokeBattle_Trainer
|
|||||||
ret.character_ID = trainer.metaID if trainer.metaID
|
ret.character_ID = trainer.metaID if trainer.metaID
|
||||||
ret.outfit = trainer.outfit if trainer.outfit
|
ret.outfit = trainer.outfit if trainer.outfit
|
||||||
ret.language = trainer.language if trainer.language
|
ret.language = trainer.language if trainer.language
|
||||||
trainer.party.each { |p| ret.party.push(Pokemon.copy(p)) }
|
trainer.party.each { |p| ret.party.push(PokeBattle_Pokemon.copy(p)) }
|
||||||
ret.badges = trainer.badges.clone
|
ret.badges = trainer.badges.clone
|
||||||
ret.money = trainer.money
|
ret.money = trainer.money
|
||||||
trainer.seen.each_with_index { |value, i| ret.set_seen(i) if value }
|
trainer.seen.each_with_index { |value, i| ret.set_seen(i) if value }
|
||||||
|
|||||||
@@ -20,13 +20,15 @@ class PokeBattle_Pokemon
|
|||||||
attr_reader :trainerID, :ot, :otgender, :language
|
attr_reader :trainerID, :ot, :otgender, :language
|
||||||
attr_reader :shadow, :heartgauge, :savedexp, :savedev, :hypermode, :shadowmoves
|
attr_reader :shadow, :heartgauge, :savedexp, :savedev, :hypermode, :shadowmoves
|
||||||
|
|
||||||
def initialise
|
def initialize(*args)
|
||||||
raise "PokeBattle_Pokemon.new is deprecated. Use Pokemon.new instead."
|
raise "PokeBattle_Pokemon.new is deprecated. Use Pokemon.new instead."
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.copy(pkmn)
|
def self.copy(pkmn)
|
||||||
|
return pkmn if pkmn.is_a?(Pokemon)
|
||||||
owner = Pokemon::Owner.new(pkmn.trainerID, pkmn.ot, pkmn.otgender, pkmn.language)
|
owner = Pokemon::Owner.new(pkmn.trainerID, pkmn.ot, pkmn.otgender, pkmn.language)
|
||||||
ret = Pokemon.new(pkmn.species, pkmn.level, owner, false)
|
# Set level to 1 initially, as it will be recalculated later
|
||||||
|
ret = Pokemon.new(pkmn.species, 1, owner, false)
|
||||||
ret.forced_form = pkmn.forcedForm if pkmn.forcedForm
|
ret.forced_form = pkmn.forcedForm if pkmn.forcedForm
|
||||||
ret.time_form_set = pkmn.formTime
|
ret.time_form_set = pkmn.formTime
|
||||||
ret.exp = pkmn.exp
|
ret.exp = pkmn.exp
|
||||||
|
|||||||
@@ -98,20 +98,20 @@ end
|
|||||||
#
|
#
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
class PokemonLoad_Scene
|
class PokemonLoad_Scene
|
||||||
def pbStartScene(commands,showContinue,trainer,framecount,mapid)
|
def pbStartScene(commands, show_continue, trainer, frame_count, map_id)
|
||||||
@commands = commands
|
@commands = commands
|
||||||
@sprites = {}
|
@sprites = {}
|
||||||
@viewport = Viewport.new(0,0,Graphics.width,Graphics.height)
|
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
|
||||||
@viewport.z = 99998
|
@viewport.z = 99998
|
||||||
addBackgroundOrColoredPlane(@sprites,"background","loadbg",Color.new(248,248,248),@viewport)
|
addBackgroundOrColoredPlane(@sprites,"background","loadbg",Color.new(248,248,248),@viewport)
|
||||||
y = 16*2
|
y = 16*2
|
||||||
for i in 0...commands.length
|
for i in 0...commands.length
|
||||||
@sprites["panel#{i}"] = PokemonLoadPanel.new(i,commands[i],
|
@sprites["panel#{i}"] = PokemonLoadPanel.new(i,commands[i],
|
||||||
(showContinue) ? (i==0) : false,trainer,framecount,mapid,@viewport)
|
(show_continue) ? (i==0) : false,trainer,frame_count,map_id,@viewport)
|
||||||
@sprites["panel#{i}"].x = 24*2
|
@sprites["panel#{i}"].x = 24*2
|
||||||
@sprites["panel#{i}"].y = y
|
@sprites["panel#{i}"].y = y
|
||||||
@sprites["panel#{i}"].pbRefresh
|
@sprites["panel#{i}"].pbRefresh
|
||||||
y += (showContinue && i==0) ? 112*2 : 24*2
|
y += (show_continue && i==0) ? 112*2 : 24*2
|
||||||
end
|
end
|
||||||
@sprites["cmdwindow"] = Window_CommandPokemon.new([])
|
@sprites["cmdwindow"] = Window_CommandPokemon.new([])
|
||||||
@sprites["cmdwindow"].viewport = @viewport
|
@sprites["cmdwindow"].viewport = @viewport
|
||||||
@@ -212,41 +212,52 @@ end
|
|||||||
class PokemonLoadScreen
|
class PokemonLoadScreen
|
||||||
def initialize(scene)
|
def initialize(scene)
|
||||||
@scene = scene
|
@scene = scene
|
||||||
|
if SaveData.exists?
|
||||||
|
@save_data = load_save_file(SaveData::FILE_PATH)
|
||||||
|
else
|
||||||
|
@save_data = {}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbTryLoadFile(savefile)
|
# @param file_path [String] file to load save data from
|
||||||
trainer = nil
|
# @return [Hash] save data
|
||||||
framecount = nil
|
def load_save_file(file_path)
|
||||||
game_system = nil
|
save_data = SaveData.read_from_file(file_path)
|
||||||
pokemonSystem = nil
|
|
||||||
mapid = nil
|
unless SaveData.valid?(save_data)
|
||||||
File.open(savefile) { |f|
|
if File.file?(file_path + '.bak')
|
||||||
trainer = Marshal.load(f)
|
pbMessage(_INTL('The save file is corrupt. A backup will be loaded.'))
|
||||||
framecount = Marshal.load(f)
|
save_data = load_save_file(file_path + '.bak')
|
||||||
game_system = Marshal.load(f)
|
else
|
||||||
pokemonSystem = Marshal.load(f)
|
self.prompt_save_deletion
|
||||||
mapid = Marshal.load(f)
|
return {}
|
||||||
}
|
end
|
||||||
raise "Corrupted file" if !trainer.is_a?(PlayerTrainer)
|
end
|
||||||
raise "Corrupted file" if !framecount.is_a?(Numeric)
|
|
||||||
raise "Corrupted file" if !game_system.is_a?(Game_System)
|
return save_data
|
||||||
raise "Corrupted file" if !pokemonSystem.is_a?(PokemonSystem)
|
end
|
||||||
raise "Corrupted file" if !mapid.is_a?(Numeric)
|
|
||||||
return [trainer,framecount,game_system,pokemonSystem,mapid]
|
# Called if all save data is invalid.
|
||||||
|
# Prompts the player to delete the save files.
|
||||||
|
def prompt_save_deletion
|
||||||
|
pbMessage(_INTL('The save file is corrupt, or is incompatible with this game.'))
|
||||||
|
exit unless pbConfirmMessageSerious(
|
||||||
|
_INTL('Do you want to delete the save file and start anew?')
|
||||||
|
)
|
||||||
|
self.delete_save_data
|
||||||
|
$game_system = Game_System.new
|
||||||
|
$PokemonSystem = PokemonSystem.new
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbStartDeleteScreen
|
def pbStartDeleteScreen
|
||||||
savefile = RTP.getSaveFileName("Game.rxdata")
|
|
||||||
@scene.pbStartDeleteScene
|
@scene.pbStartDeleteScene
|
||||||
@scene.pbStartScene2
|
@scene.pbStartScene2
|
||||||
if safeExists?(savefile)
|
if SaveData.exists?
|
||||||
if pbConfirmMessageSerious(_INTL("Delete all saved data?"))
|
if pbConfirmMessageSerious(_INTL("Delete all saved data?"))
|
||||||
pbMessage(_INTL("Once data has been deleted, there is no way to recover it.\1"))
|
pbMessage(_INTL("Once data has been deleted, there is no way to recover it.\1"))
|
||||||
if pbConfirmMessageSerious(_INTL("Delete the saved data anyway?"))
|
if pbConfirmMessageSerious(_INTL("Delete the saved data anyway?"))
|
||||||
pbMessage(_INTL("Deleting all data. Don't turn off the power.\\wtnp[0]"))
|
pbMessage(_INTL("Deleting all data. Don't turn off the power.\\wtnp[0]"))
|
||||||
begin; File.delete(savefile); rescue; end
|
self.delete_save_data
|
||||||
begin; File.delete(savefile+".bak"); rescue; end
|
|
||||||
pbMessage(_INTL("The save file was deleted."))
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
@@ -256,226 +267,82 @@ class PokemonLoadScreen
|
|||||||
$scene = pbCallTitle
|
$scene = pbCallTitle
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def delete_save_data
|
||||||
|
begin
|
||||||
|
SaveData.delete_file
|
||||||
|
pbMessage(_INTL('The saved data was deleted.'))
|
||||||
|
rescue SystemCallError
|
||||||
|
pbMessage(_INTL('All saved data could not be deleted.'))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def pbStartLoadScreen
|
def pbStartLoadScreen
|
||||||
$PokemonTemp = PokemonTemp.new
|
|
||||||
$game_temp = Game_Temp.new
|
|
||||||
$game_system = Game_System.new
|
|
||||||
$PokemonSystem = PokemonSystem.new if !$PokemonSystem
|
|
||||||
savefile = RTP.getSaveFileName("Game.rxdata")
|
|
||||||
mapfile = sprintf("Data/Map%03d.rxdata", $data_system.start_map_id)
|
|
||||||
if $data_system.start_map_id == 0 || !pbRgssExists?(mapfile)
|
|
||||||
pbMessage(_INTL("No starting position was set in the map editor.\1"))
|
|
||||||
pbMessage(_INTL("The game cannot continue."))
|
|
||||||
@scene.pbEndScene
|
|
||||||
$scene = nil
|
|
||||||
return
|
|
||||||
end
|
|
||||||
commands = []
|
commands = []
|
||||||
cmdContinue = -1
|
cmd_continue = -1
|
||||||
cmdNewGame = -1
|
cmd_new_game = -1
|
||||||
cmdOption = -1
|
cmd_options = -1
|
||||||
cmdLanguage = -1
|
cmd_language = -1
|
||||||
cmdMysteryGift = -1
|
cmd_mystery_gift = -1
|
||||||
cmdDebug = -1
|
cmd_debug = -1
|
||||||
cmdQuit = -1
|
cmd_quit = -1
|
||||||
if safeExists?(savefile)
|
show_continue = !@save_data.empty?
|
||||||
trainer = nil
|
if show_continue
|
||||||
framecount = 0
|
commands[cmd_continue = commands.length] = _INTL('Continue')
|
||||||
mapid = 0
|
if @save_data[:player].mystery_gift_unlocked
|
||||||
haveBackup = false
|
commands[cmd_mystery_gift = commands.length] = _INTL('Mystery Gift')
|
||||||
showContinue = false
|
|
||||||
begin
|
|
||||||
trainer, framecount, $game_system, $PokemonSystem, mapid = pbTryLoadFile(savefile)
|
|
||||||
showContinue = true
|
|
||||||
rescue
|
|
||||||
if safeExists?(savefile+".bak")
|
|
||||||
begin
|
|
||||||
trainer, framecount, $game_system, $PokemonSystem, mapid = pbTryLoadFile(savefile+".bak")
|
|
||||||
haveBackup = true
|
|
||||||
showContinue = true
|
|
||||||
rescue
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if haveBackup
|
commands[cmd_new_game = commands.length] = _INTL('New Game')
|
||||||
pbMessage(_INTL("The save file is corrupt. The previous save file will be loaded."))
|
commands[cmd_options = commands.length] = _INTL('Options')
|
||||||
else
|
commands[cmd_language = commands.length] = _INTL('Language') if Settings::LANGUAGES.length >= 2
|
||||||
pbMessage(_INTL("The save file is corrupt, or is incompatible with this game."))
|
commands[cmd_debug = commands.length] = _INTL('Debug') if $DEBUG
|
||||||
if !pbConfirmMessageSerious(_INTL("Do you want to delete the save file and start anew?"))
|
commands[cmd_quit = commands.length] = _INTL('Quit Game')
|
||||||
$scene = nil
|
map_id = show_continue ? @save_data[:map_factory].map.map_id : 0
|
||||||
return
|
@scene.pbStartScene(commands, show_continue, @save_data[:player],
|
||||||
end
|
@save_data[:frame_count] || 0, map_id)
|
||||||
begin; File.delete(savefile); rescue; end
|
@scene.pbSetParty(@save_data[:player]) if show_continue
|
||||||
begin; File.delete(savefile+".bak"); rescue; end
|
|
||||||
$game_system = Game_System.new
|
|
||||||
$PokemonSystem = PokemonSystem.new if !$PokemonSystem
|
|
||||||
pbMessage(_INTL("The save file was deleted."))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
if showContinue
|
|
||||||
if !haveBackup
|
|
||||||
begin; File.delete(savefile+".bak"); rescue; end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
commands[cmdContinue = commands.length] = _INTL("Continue") if showContinue
|
|
||||||
commands[cmdNewGame = commands.length] = _INTL("New Game")
|
|
||||||
commands[cmdMysteryGift = commands.length] = _INTL("Mystery Gift") if trainer.mystery_gift_unlocked
|
|
||||||
else
|
|
||||||
commands[cmdNewGame = commands.length] = _INTL("New Game")
|
|
||||||
end
|
|
||||||
commands[cmdOption = commands.length] = _INTL("Options")
|
|
||||||
commands[cmdLanguage = commands.length] = _INTL("Language") if Settings::LANGUAGES.length>=2
|
|
||||||
commands[cmdDebug = commands.length] = _INTL("Debug") if $DEBUG
|
|
||||||
commands[cmdQuit = commands.length] = _INTL("Quit Game")
|
|
||||||
@scene.pbStartScene(commands,showContinue,trainer,framecount,mapid)
|
|
||||||
@scene.pbSetParty(trainer) if showContinue
|
|
||||||
@scene.pbStartScene2
|
@scene.pbStartScene2
|
||||||
pbLoadBattleAnimations
|
|
||||||
loop do
|
loop do
|
||||||
command = @scene.pbChoose(commands)
|
command = @scene.pbChoose(commands)
|
||||||
if cmdContinue>=0 && command==cmdContinue
|
pbPlayDecisionSE if command != cmd_quit
|
||||||
unless safeExists?(savefile)
|
case command
|
||||||
pbPlayBuzzerSE
|
when cmd_continue
|
||||||
next
|
|
||||||
end
|
|
||||||
pbPlayDecisionSE
|
|
||||||
@scene.pbEndScene
|
@scene.pbEndScene
|
||||||
metadata = nil
|
Game.load(@save_data)
|
||||||
File.open(savefile) { |f|
|
|
||||||
Marshal.load(f) # Trainer already loaded
|
|
||||||
$Trainer = trainer
|
|
||||||
Graphics.frame_count = Marshal.load(f)
|
|
||||||
$game_system = Marshal.load(f)
|
|
||||||
Marshal.load(f) # PokemonSystem already loaded
|
|
||||||
Marshal.load(f) # Current map id no longer needed
|
|
||||||
$game_switches = Marshal.load(f)
|
|
||||||
$game_variables = Marshal.load(f)
|
|
||||||
$game_self_switches = Marshal.load(f)
|
|
||||||
$game_screen = Marshal.load(f)
|
|
||||||
$MapFactory = Marshal.load(f)
|
|
||||||
$game_map = $MapFactory.map
|
|
||||||
$game_player = Marshal.load(f)
|
|
||||||
$PokemonGlobal = Marshal.load(f)
|
|
||||||
metadata = Marshal.load(f)
|
|
||||||
$PokemonBag = Marshal.load(f)
|
|
||||||
$PokemonStorage = Marshal.load(f)
|
|
||||||
$SaveVersion = Marshal.load(f) unless f.eof?
|
|
||||||
magicNumberMatches = false
|
|
||||||
if $data_system.respond_to?("magic_number")
|
|
||||||
magicNumberMatches = ($game_system.magic_number==$data_system.magic_number)
|
|
||||||
else
|
|
||||||
magicNumberMatches = ($game_system.magic_number==$data_system.version_id)
|
|
||||||
end
|
|
||||||
if !magicNumberMatches || $PokemonGlobal.safesave
|
|
||||||
if pbMapInterpreterRunning?
|
|
||||||
pbMapInterpreter.setup(nil,0)
|
|
||||||
end
|
|
||||||
begin
|
|
||||||
$MapFactory.setup($game_map.map_id) # calls setMapChanged
|
|
||||||
rescue Errno::ENOENT
|
|
||||||
if $DEBUG
|
|
||||||
pbMessage(_INTL("Map {1} was not found.",$game_map.map_id))
|
|
||||||
map = pbWarpToMap
|
|
||||||
if map
|
|
||||||
$MapFactory.setup(map[0])
|
|
||||||
$game_player.moveto(map[1],map[2])
|
|
||||||
else
|
|
||||||
$game_map = nil
|
|
||||||
$scene = nil
|
|
||||||
return
|
return
|
||||||
end
|
when cmd_new_game
|
||||||
else
|
|
||||||
$game_map = nil
|
|
||||||
$scene = nil
|
|
||||||
pbMessage(_INTL("The map was not found. The game cannot continue."))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
$game_player.center($game_player.x, $game_player.y)
|
|
||||||
else
|
|
||||||
$MapFactory.setMapChanged($game_map.map_id)
|
|
||||||
end
|
|
||||||
}
|
|
||||||
if !$game_map.events # Map wasn't set up
|
|
||||||
$game_map = nil
|
|
||||||
$scene = nil
|
|
||||||
pbMessage(_INTL("The map is corrupt. The game cannot continue."))
|
|
||||||
return
|
|
||||||
end
|
|
||||||
$PokemonMap = metadata
|
|
||||||
$PokemonEncounters = PokemonEncounters.new
|
|
||||||
$PokemonEncounters.setup($game_map.map_id)
|
|
||||||
pbAutoplayOnSave
|
|
||||||
$game_map.update
|
|
||||||
$PokemonMap.updateMap
|
|
||||||
$scene = Scene_Map.new
|
|
||||||
return
|
|
||||||
elsif cmdNewGame>=0 && command==cmdNewGame
|
|
||||||
pbPlayDecisionSE
|
|
||||||
@scene.pbEndScene
|
@scene.pbEndScene
|
||||||
if $game_map && $game_map.events
|
Game.start_new
|
||||||
for event in $game_map.events.values
|
|
||||||
event.clear_starting
|
|
||||||
end
|
|
||||||
end
|
|
||||||
$game_temp.common_event_id = 0 if $game_temp
|
|
||||||
$scene = Scene_Map.new
|
|
||||||
Graphics.frame_count = 0
|
|
||||||
$game_system = Game_System.new
|
|
||||||
$game_switches = Game_Switches.new
|
|
||||||
$game_variables = Game_Variables.new
|
|
||||||
$game_self_switches = Game_SelfSwitches.new
|
|
||||||
$game_screen = Game_Screen.new
|
|
||||||
$game_player = Game_Player.new
|
|
||||||
$PokemonMap = PokemonMapMetadata.new
|
|
||||||
$PokemonGlobal = PokemonGlobalMetadata.new
|
|
||||||
$PokemonStorage = PokemonStorage.new
|
|
||||||
$PokemonEncounters = PokemonEncounters.new
|
|
||||||
$PokemonTemp.begunNewGame = true
|
|
||||||
$MapFactory = PokemonMapFactory.new($data_system.start_map_id) # calls setMapChanged
|
|
||||||
$game_player.moveto($data_system.start_x, $data_system.start_y)
|
|
||||||
$game_player.refresh
|
|
||||||
$game_map.autoplay
|
|
||||||
$game_map.update
|
|
||||||
return
|
return
|
||||||
elsif cmdMysteryGift>=0 && command==cmdMysteryGift
|
when cmd_mystery_gift
|
||||||
pbPlayDecisionSE
|
pbFadeOutIn do
|
||||||
pbFadeOutIn {
|
@save_data[:player] = pbDownloadMysteryGift(@save_data[:player])
|
||||||
trainer = pbDownloadMysteryGift(trainer)
|
end
|
||||||
}
|
when cmd_options
|
||||||
elsif cmdOption>=0 && command==cmdOption
|
pbFadeOutIn do
|
||||||
pbPlayDecisionSE
|
|
||||||
pbFadeOutIn {
|
|
||||||
scene = PokemonOption_Scene.new
|
scene = PokemonOption_Scene.new
|
||||||
screen = PokemonOptionScreen.new(scene)
|
screen = PokemonOptionScreen.new(scene)
|
||||||
screen.pbStartScreen(true)
|
screen.pbStartScreen(true)
|
||||||
}
|
end
|
||||||
elsif cmdLanguage>=0 && command==cmdLanguage
|
when cmd_language
|
||||||
pbPlayDecisionSE
|
|
||||||
@scene.pbEndScene
|
@scene.pbEndScene
|
||||||
$PokemonSystem.language = pbChooseLanguage
|
$PokemonSystem.language = pbChooseLanguage
|
||||||
pbLoadMessages("Data/"+Settings::LANGUAGES[$PokemonSystem.language][1])
|
pbLoadMessages('Data/' + Settings::LANGUAGES[$PokemonSystem.language][1])
|
||||||
savedata = []
|
if show_continue
|
||||||
if safeExists?(savefile)
|
@save_data[:pokemon_system] = $PokemonSystem
|
||||||
File.open(savefile,"rb") { |f|
|
File.open(SaveData::FILE_PATH, 'wb') { |file| Marshal.dump(@save_data, file) }
|
||||||
16.times { savedata.push(Marshal.load(f)) }
|
|
||||||
}
|
|
||||||
savedata[3]=$PokemonSystem
|
|
||||||
begin
|
|
||||||
File.open(RTP.getSaveFileName("Game.rxdata"),"wb") { |f|
|
|
||||||
16.times { |i| Marshal.dump(savedata[i],f) }
|
|
||||||
}
|
|
||||||
rescue
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
$scene = pbCallTitle
|
$scene = pbCallTitle
|
||||||
return
|
return
|
||||||
elsif cmdDebug>=0 && command==cmdDebug
|
when cmd_debug
|
||||||
pbPlayDecisionSE
|
|
||||||
pbFadeOutIn { pbDebugMenu(false) }
|
pbFadeOutIn { pbDebugMenu(false) }
|
||||||
elsif cmdQuit>=0 && command==cmdQuit
|
when cmd_quit
|
||||||
pbPlayCloseMenuSE
|
pbPlayCloseMenuSE
|
||||||
@scene.pbEndScene
|
@scene.pbEndScene
|
||||||
$scene = nil
|
$scene = nil
|
||||||
return
|
return
|
||||||
|
else
|
||||||
|
pbPlayBuzzerSE
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,60 +1,29 @@
|
|||||||
#===============================================================================
|
# @deprecated Use {Game.save} instead. pbSave is slated to be removed in v20.
|
||||||
#
|
def pbSave(safesave = false)
|
||||||
#===============================================================================
|
Deprecation.warn_method('pbSave', 'Game.save', 'v20')
|
||||||
def pbSave(safesave=false)
|
Game.save(safe: safesave)
|
||||||
begin
|
|
||||||
File.open(RTP.getSaveFileName("Game.rxdata"),"wb") { |f|
|
|
||||||
Marshal.dump($Trainer,f)
|
|
||||||
Marshal.dump(Graphics.frame_count,f)
|
|
||||||
if $data_system.respond_to?("magic_number")
|
|
||||||
$game_system.magic_number = $data_system.magic_number
|
|
||||||
else
|
|
||||||
$game_system.magic_number = $data_system.version_id
|
|
||||||
end
|
|
||||||
$game_system.save_count+=1
|
|
||||||
Marshal.dump($game_system,f)
|
|
||||||
Marshal.dump($PokemonSystem,f)
|
|
||||||
Marshal.dump($game_map.map_id,f)
|
|
||||||
Marshal.dump($game_switches,f)
|
|
||||||
Marshal.dump($game_variables,f)
|
|
||||||
Marshal.dump($game_self_switches,f)
|
|
||||||
Marshal.dump($game_screen,f)
|
|
||||||
Marshal.dump($MapFactory,f)
|
|
||||||
Marshal.dump($game_player,f)
|
|
||||||
$PokemonGlobal.safesave=safesave
|
|
||||||
Marshal.dump($PokemonGlobal,f)
|
|
||||||
Marshal.dump($PokemonMap,f)
|
|
||||||
Marshal.dump($PokemonBag,f)
|
|
||||||
Marshal.dump($PokemonStorage,f)
|
|
||||||
Marshal.dump(Essentials::VERSION, f)
|
|
||||||
}
|
|
||||||
Graphics.frame_reset
|
|
||||||
rescue
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbEmergencySave
|
def pbEmergencySave
|
||||||
oldscene=$scene
|
oldscene = $scene
|
||||||
$scene=nil
|
$scene = nil
|
||||||
pbMessage(_INTL("The script is taking too long. The game will restart."))
|
pbMessage(_INTL("The script is taking too long. The game will restart."))
|
||||||
return if !$Trainer
|
return if !$Trainer
|
||||||
if safeExists?(RTP.getSaveFileName("Game.rxdata"))
|
if SaveData.exists?
|
||||||
File.open(RTP.getSaveFileName("Game.rxdata"), 'rb') { |r|
|
File.open(SaveData::FILE_PATH, 'rb') do |r|
|
||||||
File.open(RTP.getSaveFileName("Game.rxdata.bak"), 'wb') { |w|
|
File.open(SaveData::FILE_PATH + '.bak', 'wb') do |w|
|
||||||
while s = r.read(4096)
|
while s = r.read(4096)
|
||||||
w.write s
|
w.write s
|
||||||
end
|
end
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
if pbSave
|
end
|
||||||
|
end
|
||||||
|
if Game.save
|
||||||
pbMessage(_INTL("\\se[]The game was saved.\\me[GUI save game] The previous save file has been backed up.\\wtnp[30]"))
|
pbMessage(_INTL("\\se[]The game was saved.\\me[GUI save game] The previous save file has been backed up.\\wtnp[30]"))
|
||||||
else
|
else
|
||||||
pbMessage(_INTL("\\se[]Save failed.\\wtnp[30]"))
|
pbMessage(_INTL("\\se[]Save failed.\\wtnp[30]"))
|
||||||
end
|
end
|
||||||
$scene=oldscene
|
$scene = oldscene
|
||||||
end
|
end
|
||||||
|
|
||||||
#===============================================================================
|
#===============================================================================
|
||||||
@@ -117,33 +86,31 @@ class PokemonSaveScreen
|
|||||||
end
|
end
|
||||||
|
|
||||||
def pbSaveScreen
|
def pbSaveScreen
|
||||||
ret=false
|
ret = false
|
||||||
@scene.pbStartScreen
|
@scene.pbStartScreen
|
||||||
if pbConfirmMessage(_INTL("Would you like to save the game?"))
|
if pbConfirmMessage(_INTL('Would you like to save the game?'))
|
||||||
if safeExists?(RTP.getSaveFileName("Game.rxdata"))
|
if SaveData.exists? && $PokemonTemp.begunNewGame
|
||||||
if $PokemonTemp.begunNewGame
|
pbMessage(_INTL('WARNING!'))
|
||||||
pbMessage(_INTL("WARNING!"))
|
pbMessage(_INTL('There is a different game file that is already saved.'))
|
||||||
pbMessage(_INTL("There is a different game file that is already saved."))
|
|
||||||
pbMessage(_INTL("If you save now, the other file's adventure, including items and Pokémon, will be entirely lost."))
|
pbMessage(_INTL("If you save now, the other file's adventure, including items and Pokémon, will be entirely lost."))
|
||||||
if !pbConfirmMessageSerious(
|
if !pbConfirmMessageSerious(
|
||||||
_INTL("Are you sure you want to save now and overwrite the other save file?"))
|
_INTL('Are you sure you want to save now and overwrite the other save file?'))
|
||||||
pbSEPlay("GUI save choice")
|
pbSEPlay('GUI save choice')
|
||||||
@scene.pbEndScreen
|
@scene.pbEndScreen
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
$PokemonTemp.begunNewGame = false
|
||||||
$PokemonTemp.begunNewGame=false
|
pbSEPlay('GUI save choice')
|
||||||
pbSEPlay("GUI save choice")
|
if Game.save
|
||||||
if pbSave
|
pbMessage(_INTL("\\se[]{1} saved the game.\\me[GUI save game]\\wtnp[30]", $Trainer.name))
|
||||||
pbMessage(_INTL("\\se[]{1} saved the game.\\me[GUI save game]\\wtnp[30]",$Trainer.name))
|
ret = true
|
||||||
ret=true
|
|
||||||
else
|
else
|
||||||
pbMessage(_INTL("\\se[]Save failed.\\wtnp[30]"))
|
pbMessage(_INTL("\\se[]Save failed.\\wtnp[30]"))
|
||||||
ret=false
|
ret = false
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
pbSEPlay("GUI save choice")
|
pbSEPlay('GUI save choice')
|
||||||
end
|
end
|
||||||
@scene.pbEndScreen
|
@scene.pbEndScreen
|
||||||
return ret
|
return ret
|
||||||
|
|||||||
@@ -355,7 +355,7 @@ class BattleChallengeData
|
|||||||
@start=[$game_map.map_id,$game_player.x,$game_player.y]
|
@start=[$game_map.map_id,$game_player.x,$game_player.y]
|
||||||
@oldParty=$Trainer.party
|
@oldParty=$Trainer.party
|
||||||
$Trainer.party=@party if @party
|
$Trainer.party=@party if @party
|
||||||
pbSave(true)
|
Game.save(safe: true)
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbCancel
|
def pbCancel
|
||||||
@@ -369,9 +369,7 @@ class BattleChallengeData
|
|||||||
save=(@decision!=0)
|
save=(@decision!=0)
|
||||||
reset
|
reset
|
||||||
$game_map.need_refresh=true
|
$game_map.need_refresh=true
|
||||||
if save
|
Game.save(safe: true) if save
|
||||||
pbSave(true)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def pbGoOn
|
def pbGoOn
|
||||||
@@ -410,7 +408,7 @@ class BattleChallengeData
|
|||||||
$game_map.map_id=@start[0]
|
$game_map.map_id=@start[0]
|
||||||
$game_player.moveto2(@start[1],@start[2])
|
$game_player.moveto2(@start[1],@start[2])
|
||||||
$game_player.direction=8 # facing up
|
$game_player.direction=8 # facing up
|
||||||
pbSave(true)
|
Game.save(safe: true)
|
||||||
$game_map.map_id=oldmapid
|
$game_map.map_id=oldmapid
|
||||||
$game_player.moveto2(oldx,oldy)
|
$game_player.moveto2(oldx,oldy)
|
||||||
$game_player.direction=olddirection
|
$game_player.direction=olddirection
|
||||||
|
|||||||
@@ -16,44 +16,6 @@ def pbChooseLanguage
|
|||||||
return pbShowCommands(nil,commands)
|
return pbShowCommands(nil,commands)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def pbSetUpSystem
|
|
||||||
begin
|
|
||||||
trainer = nil
|
|
||||||
framecount = 0
|
|
||||||
game_system = nil
|
|
||||||
pokemonSystem = nil
|
|
||||||
havedata = false
|
|
||||||
File.open(RTP.getSaveFileName("Game.rxdata")) { |f|
|
|
||||||
trainer = Marshal.load(f)
|
|
||||||
framecount = Marshal.load(f)
|
|
||||||
game_system = Marshal.load(f)
|
|
||||||
pokemonSystem = Marshal.load(f)
|
|
||||||
}
|
|
||||||
raise "Corrupted file" if !trainer.is_a?(PlayerTrainer)
|
|
||||||
raise "Corrupted file" if !framecount.is_a?(Numeric)
|
|
||||||
raise "Corrupted file" if !game_system.is_a?(Game_System)
|
|
||||||
raise "Corrupted file" if !pokemonSystem.is_a?(PokemonSystem)
|
|
||||||
havedata = true
|
|
||||||
rescue
|
|
||||||
game_system = Game_System.new
|
|
||||||
pokemonSystem = PokemonSystem.new
|
|
||||||
end
|
|
||||||
if $INEDITOR
|
|
||||||
pbSetResizeFactor(1.0)
|
|
||||||
else
|
|
||||||
$game_system = game_system
|
|
||||||
$PokemonSystem = pokemonSystem
|
|
||||||
pbSetResizeFactor([$PokemonSystem.screensize, 4].min)
|
|
||||||
end
|
|
||||||
# Load constants
|
|
||||||
GameData.load_all
|
|
||||||
if Settings::LANGUAGES.length>=2
|
|
||||||
pokemonSystem.language = pbChooseLanguage if !havedata
|
|
||||||
pbLoadMessages("Data/"+Settings::LANGUAGES[pokemonSystem.language][1])
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def pbScreenCapture
|
def pbScreenCapture
|
||||||
t = pbGetTimeNow
|
t = pbGetTimeNow
|
||||||
filestart = t.strftime("[%Y-%m-%d] %H_%M_%S")
|
filestart = t.strftime("[%Y-%m-%d] %H_%M_%S")
|
||||||
|
|||||||
136
Data/Scripts/020_System and utilities/006_Game.rb
Normal file
136
Data/Scripts/020_System and utilities/006_Game.rb
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
# The Game module contains methods for saving and loading the game.
|
||||||
|
module Game
|
||||||
|
# Initializes various global variables and loads the game data.
|
||||||
|
def self.initialize
|
||||||
|
$PokemonTemp = PokemonTemp.new
|
||||||
|
$game_temp = Game_Temp.new
|
||||||
|
$game_system = Game_System.new
|
||||||
|
$data_animations = load_data('Data/Animations.rxdata')
|
||||||
|
$data_tilesets = load_data('Data/Tilesets.rxdata')
|
||||||
|
$data_common_events = load_data('Data/CommonEvents.rxdata')
|
||||||
|
$data_system = load_data('Data/System.rxdata')
|
||||||
|
pbLoadBattleAnimations
|
||||||
|
GameData.load_all
|
||||||
|
|
||||||
|
map_file = format('Data/Map%03d.rxdata', $data_system.start_map_id)
|
||||||
|
|
||||||
|
if $data_system.start_map_id == 0 || !pbRgssExists?(map_file)
|
||||||
|
raise _INTL('No starting position was set in the map editor.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Loads values from the save file and runs any necessary
|
||||||
|
# conversions on it.
|
||||||
|
def self.set_up_system
|
||||||
|
SaveData.move_old_windows_save if System.platform[/Windows/]
|
||||||
|
|
||||||
|
if SaveData.exists?
|
||||||
|
save_data = SaveData.read_from_file(SaveData::FILE_PATH)
|
||||||
|
else
|
||||||
|
save_data = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if !save_data.empty? && SaveData.run_conversions(save_data)
|
||||||
|
File.open(SaveData::FILE_PATH, 'wb') { |f| Marshal.dump(save_data, f) }
|
||||||
|
end
|
||||||
|
|
||||||
|
if save_data.empty?
|
||||||
|
SaveData.initialize_bootup_values
|
||||||
|
else
|
||||||
|
SaveData.load_bootup_values(save_data)
|
||||||
|
end
|
||||||
|
|
||||||
|
pbSetResizeFactor([$PokemonSystem.screensize, 4].min)
|
||||||
|
if Settings::LANGUAGES.length >= 2
|
||||||
|
$PokemonSystem.language = pbChooseLanguage if save_data.empty?
|
||||||
|
pbLoadMessages('Data/' + Settings::LANGUAGES[$PokemonSystem.language][1])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Saves the game. Returns whether the operation was successful.
|
||||||
|
# @param save_file [String] the save file path
|
||||||
|
# @param safe [Boolean] whether $PokemonGlobal.safesave should be set to true
|
||||||
|
# @return [Boolean] whether the operation was successful
|
||||||
|
# @raise [SaveData::InvalidValueError] if an invalid value is being saved
|
||||||
|
def self.save(save_file = SaveData::FILE_PATH, safe: false)
|
||||||
|
validate save_file => String, safe => [TrueClass, FalseClass]
|
||||||
|
|
||||||
|
$PokemonGlobal.safesave = safe
|
||||||
|
$game_system.save_count += 1
|
||||||
|
$game_system.magic_number = $data_system.magic_number
|
||||||
|
begin
|
||||||
|
SaveData.save_to_file(save_file)
|
||||||
|
Graphics.frame_reset
|
||||||
|
rescue IOError, SystemCallError
|
||||||
|
$game_system.save_count -= 1
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
# Loads the game from the given save data and starts the map scene.
|
||||||
|
# @param save_data [Hash] hash containing the save data
|
||||||
|
# @raise [SaveData::InvalidValueError] if an invalid value is being loaded
|
||||||
|
def self.load(save_data)
|
||||||
|
validate save_data => Hash
|
||||||
|
|
||||||
|
SaveData.load_all_values(save_data)
|
||||||
|
|
||||||
|
self.load_map
|
||||||
|
|
||||||
|
pbAutoplayOnSave
|
||||||
|
$game_map.update
|
||||||
|
$PokemonMap.updateMap
|
||||||
|
$scene = Scene_Map.new
|
||||||
|
end
|
||||||
|
|
||||||
|
# Loads and validates the map. Called when loading a saved game.
|
||||||
|
def self.load_map
|
||||||
|
$game_map = $MapFactory.map
|
||||||
|
magic_number_matches = ($game_system.magic_number == $data_system.magic_number)
|
||||||
|
if !magic_number_matches || $PokemonGlobal.safesave
|
||||||
|
if pbMapInterpreterRunning?
|
||||||
|
pbMapInterpreter.setup(nil, 0)
|
||||||
|
end
|
||||||
|
begin
|
||||||
|
$MapFactory.setup($game_map.map_id)
|
||||||
|
rescue Errno::ENOENT
|
||||||
|
if $DEBUG
|
||||||
|
pbMessage(_INTL('Map {1} was not found.', $game_map.map_id))
|
||||||
|
map = pbWarpToMap
|
||||||
|
exit unless map
|
||||||
|
$MapFactory.setup(map[0])
|
||||||
|
$game_player.moveto(map[1], map[2])
|
||||||
|
else
|
||||||
|
raise _INTL('The map was not found. The game cannot continue.')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
$game_player.center($game_player.x, $game_player.y)
|
||||||
|
else
|
||||||
|
$MapFactory.setMapChanged($game_map.map_id)
|
||||||
|
end
|
||||||
|
if $game_map.events.nil?
|
||||||
|
raise _INTL('The map is corrupt. The game cannot continue.')
|
||||||
|
end
|
||||||
|
$PokemonEncounters = PokemonEncounters.new
|
||||||
|
$PokemonEncounters.setup($game_map.map_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Called when starting a new game. Initializes global variables
|
||||||
|
# and transfers the player into the map scene.
|
||||||
|
def self.start_new
|
||||||
|
if $game_map && $game_map.events
|
||||||
|
$game_map.events.each_value { |event| event.clear_starting }
|
||||||
|
end
|
||||||
|
$game_temp.common_event_id = 0 if $game_temp
|
||||||
|
$PokemonTemp.begunNewGame = true
|
||||||
|
$scene = Scene_Map.new
|
||||||
|
SaveData.load_new_game_values
|
||||||
|
$MapFactory = PokemonMapFactory.new($data_system.start_map_id)
|
||||||
|
$game_player.moveto($data_system.start_x, $data_system.start_y)
|
||||||
|
$game_player.refresh
|
||||||
|
$game_map.autoplay
|
||||||
|
$game_map.update
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -28,12 +28,8 @@ end
|
|||||||
def mainFunctionDebug
|
def mainFunctionDebug
|
||||||
begin
|
begin
|
||||||
Compiler.main
|
Compiler.main
|
||||||
pbSetUpSystem
|
Game.initialize
|
||||||
$data_animations = load_data("Data/Animations.rxdata")
|
Game.set_up_system
|
||||||
$data_tilesets = load_data("Data/Tilesets.rxdata")
|
|
||||||
$data_common_events = load_data("Data/CommonEvents.rxdata")
|
|
||||||
$data_system = load_data("Data/System.rxdata")
|
|
||||||
$game_system = Game_System.new
|
|
||||||
Graphics.update
|
Graphics.update
|
||||||
Graphics.freeze
|
Graphics.freeze
|
||||||
$scene = pbCallTitle
|
$scene = pbCallTitle
|
||||||
|
|||||||
Reference in New Issue
Block a user