[XP] Wecoc's Dynamic File System

Started by Wecoc, August 28, 2014, 07:49:18 pm

Previous topic - Next topic

Wecoc

August 28, 2014, 07:49:18 pm Last Edit: August 29, 2014, 01:41:18 am by KK20
Wecoc's Dynamic File System
Authors: Wecoc
Version: 1.2
Type: Save / Load Add-on
Key Term: Title / Save / Load / GameOver Add-on



Introduction

The script rewrites all the load/save system.

I created this basis so you can make your own load / save system with dynamic functions in your own way.
My recommendation is not use it alone because the interface is not pretty, but it will work anyway.



Features


  • The player can name the Save file in the same way like actors.

  • It has no max on the number of files.

  • New folder for save files. If it does not exist it will be created automatically.

  • (Not used but done) Delete save files from the game.

  • (Not used but done) Get the last saved game directly by mtime

  • Get the actual file you are playing, with $game_temp.playing_file ("" if none)




Screenshots

These are from the default interface. As I said, it's not so cool.

Screen01
Screen02
Screen03



Script

Put this script over main
Spoiler: ShowHide

#==============================================================================
# ** [XP] Wecoc's Dynamic File System v1.2
#------------------------------------------------------------------------------
# by: Wecoc
#==============================================================================

module Save_Module

 FOLDER = "Save"

 def self.folder
   save_folder = FOLDER
   if FOLDER == "" or FOLDER == nil
     save_folder = Dir.getwd
   end
   return save_folder
 end
end

class Dir
 def Dir.get_extension_files(dirname)
   Dir.open(dirname) do |d|
     if dirname == Dir.getwd
       return d.select {|ent| File.file?("#{ent}")}
     else
       return d.select {|ent| File.file?("#{dirname}/#{ent}")}
     end
   end
 end

 def Dir.get_save_files(dirname)
   folder_files = Dir.get_extension_files(dirname)
   folder_files = folder_files.select {|d| d.include?(".rxdata")}
   folder_files.each do |d|
     d.chomp!(".rxdata")
   end
   return folder_files
 end

 def Dir.last_file_played
   array = []
   Dir.get_extension_files(Save_Module.folder).each do |last|
     file = File.open("#{Save_Module.folder}/#{last}", "r")
     array.push [last, file.mtime]
   end
   array.sort! {|a, b| b[1] <=> a[1] }
   return array[0][0]
 end
end

#==============================================================================
# ** Window_VariableNameEdit
#==============================================================================

class Game_Temp
 attr_accessor :var_max_char
 attr_accessor :playing_file
 alias var_max_char_ini initialize unless $@
 def initialize
   var_max_char_ini
   @var_max_char = 16
   @playing_file = ""
 end
end

class Window_VariableNameEdit < Window_Base
 attr_reader  :name
 attr_reader  :index

 def initialize(max_char)
   super(0, 0, 640, 128)
   self.contents = Bitmap.new(width - 32, height - 32)
   @max_char = max_char
   @name = ""
   @index = 0
   refresh
   update_cursor_rect
 end

 def refresh
   self.contents.clear
   name_array = @name.split(//)
   for i in 0...@max_char
     c = name_array[i]
     if c == nil
       c = "_"
     end
     x = 320 - @max_char * 14 + i * 28
     self.contents.draw_text(x, 32, 28, 32, c, 1)
   end
 end

 def add(character)
   if @index < @max_char and character != ""
     @name += character
     @index += 1
     refresh
     update_cursor_rect
   end
 end

 def back
   if @index > 0
     name_array = @name.split(//)
     @name = ""
     for i in 0...name_array.size-1
       @name += name_array[i]
     end
     @index -= 1
     refresh
     update_cursor_rect
   end
 end

 def update_cursor_rect
   x = 320 - @max_char * 14 + @index * 28
   self.cursor_rect.set(x, 32, 28, 32)
 end

 def restore_default
   refresh
   update_cursor_rect
 end
 
 def update
   super
   update_cursor_rect
 end
end

#==============================================================================
# ** Scene_Variable_Name
#==============================================================================

class Scene_Variable_Name
 attr_accessor :variable

 def main
   @edit_window = Window_VariableNameEdit.new($game_temp.var_max_char)
   @input_window = Window_NameInput.new
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     if $scene != self
       break
     end
   end
   Graphics.freeze
   @edit_window.dispose
   @input_window.dispose
 end

 def update
   @edit_window.update
   @input_window.update
   if Input.repeat?(Input::B)
     if @edit_window.index == 0
       $game_system.se_play($data_system.cancel_se)
       $scene = Scene_Save.new(false)
       return
     end
     $game_system.se_play($data_system.cancel_se)
     @edit_window.back
     return
   end
   if Input.trigger?(Input::C)
     if @input_window.character == nil
       if @edit_window.name == ""
         @edit_window.restore_default
         if @edit_window.name == ""
           $game_system.se_play($data_system.buzzer_se)
           return
         end
         $game_system.se_play($data_system.decision_se)
         return
       end
       $save_variable = @edit_window.name
       $game_system.se_play($data_system.decision_se)
       $scene = Scene_Save.new(true) ##
       return
     end
     if @edit_window.index == $game_temp.var_max_char
       $game_system.se_play($data_system.buzzer_se)
       return
     end
     if @input_window.character == ""
       $game_system.se_play($data_system.buzzer_se)
       return
     end
     $game_system.se_play($data_system.decision_se)
     @edit_window.add(@input_window.character)
     return
   end
 end
end

#==============================================================================
# ** Window_Confirm
#==============================================================================

class Window_Confirm < Window_Selectable
 attr_accessor :question
 attr_accessor :yes_string
 attr_accessor :no_string

 def initialize(question, yes_string, no_string, column_max=1)
   super(0, 0, 120, 160 - (column_max * 32))
   self.contents = Bitmap.new(self.width - 32, self.height - 32)
   w1 = self.contents.text_size(question).width
   w2 = self.contents.text_size(yes_string).width
   w3 = self.contents.text_size(no_string).width
   if column_max == 1
     self.width = [w1, w2, w3].max + 36
   else
     self.width = [w1, w2 + w3].max + 36
   end
   self.contents = Bitmap.new(self.width - 32, self.height - 32)
   @column_max = column_max
   @item_max = 2
   @index = 1
   @question = question
   @yes_string = yes_string
   @no_string = no_string
   draw_strings
 end

 def refresh
   self.contents.clear
   draw_strings
 end

 def draw_strings
   self.contents.draw_text(2, 0, self.width - 32, 32, @question)
   self.contents.draw_text(2, 32, self.width - 32, 32, @yes_string)
   case @column_max
   when 1
     x = 2
     y = 64
     width = self.width - 32
   when 2
     x = (self.width - 32) / 2
     y = 32
     width = (self.width - 32) / 2
   end
   self.contents.draw_text(x, y, width, 32, @no_string)
 end

 def update_cursor_rect
   if @index < 0
     self.cursor_rect.empty
     return
   end
   row = @index / @column_max
   if row < self.top_row
     self.top_row = row
   end
   if row > self.top_row + (self.page_row_max - 1)
     self.top_row = row - (self.page_row_max - 1)
   end
   cursor_width = self.width / @column_max - 32
   x = @index % @column_max * (cursor_width + 32)
   y = @index / @column_max * 32 - self.oy
   self.cursor_rect.set(x, y + 32, cursor_width, 32)
 end
end

#==============================================================================
# ** Window_File
#==============================================================================

class Window_File < Window_Selectable
 def initialize
   super(0, 64, 640, 352)
   @column_max = 1
   refresh
   self.index = 0
 end

 def item
   return @data[self.index]
 end

 def refresh
   if self.contents != nil
     self.contents.dispose
     self.contents = nil
   end
   @data = []
   # Add item
   save_files = Dir.get_save_files(Save_Module.folder)
   for i in 0...save_files.size
     @data.push(save_files[i])
   end
   # If item count is not 0, make a bit map and draw all items
   @item_max = @data.size
   if @item_max > 0
     self.contents = Bitmap.new(width - 32, row_max * 32)
     for i in 0...@item_max
       draw_item(i)
     end
   end
 end

 def draw_item(index)
   item = @data[index]
   # x = 4 + index % 2 * (288 + 32)
   # y = index / 2 * 32
   x = 4
   y = index * 32
   rect = Rect.new(x, y, self.width / @column_max - 32, 32)
   self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
   self.contents.draw_text(x, y, 640, 32, item)
 end
end

#==============================================================================
# ** Scene_Title
#==============================================================================

class Scene_Title
 def main
   if $BTEST
     battle_test
     return
   end
   $data_actors        = load_data("Data/Actors.rxdata")
   $data_classes       = load_data("Data/Classes.rxdata")
   $data_skills        = load_data("Data/Skills.rxdata")
   $data_items         = load_data("Data/Items.rxdata")
   $data_weapons       = load_data("Data/Weapons.rxdata")
   $data_armors        = load_data("Data/Armors.rxdata")
   $data_enemies       = load_data("Data/Enemies.rxdata")
   $data_troops        = load_data("Data/Troops.rxdata")
   $data_states        = load_data("Data/States.rxdata")
   $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")
   $game_system = Game_System.new
   @sprite = Sprite.new
   @sprite.bitmap = RPG::Cache.title($data_system.title_name)
   s1 = "New Game"
   s2 = "Continue"
   s3 = "Shutdown"
   @command_window = Window_Command.new(192, [s1, s2, s3])
   @command_window.back_opacity = 160
   @command_window.x = 320 - @command_window.width / 2
   @command_window.y = 288
   if Save_Module.folder != Dir.getwd
     if not Dir.entries(Dir.getwd).include?(Save_Module.folder)
       Dir.mkdir(Save_Module.folder)
     end
   end
   @continue_enabled = false
   if Dir.get_save_files(Save_Module.folder).size > 0
     @continue_enabled = true
   end
   if @continue_enabled
     @command_window.index = 1
   else
     @command_window.disable_item(1)
   end
   $game_system.bgm_play($data_system.title_bgm)
   Audio.me_stop
   Audio.bgs_stop
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     if $scene != self
       break
     end
   end
   Graphics.freeze
   @command_window.dispose
   @sprite.bitmap.dispose
   @sprite.dispose
 end
end

#==============================================================================
# ** Scene_File
#==============================================================================

class Scene_File
 def make_filename(name)
   return "#{Save_Module.folder}/#{name.to_s}.rxdata"
 end

 def delete_file(filename)
   $game_system.se_play($data_system.save_se)
   File.delete(filename)
 end

 def write_save_data(file)
   characters = []
   for i in 0...$game_party.actors.size
     actor = $game_party.actors[i]
     characters.push([actor.character_name, actor.character_hue])
   end
   Marshal.dump(characters, file)
   Marshal.dump(Graphics.frame_count, file)
   $game_system.save_count += 1
   $game_system.magic_number = $data_system.magic_number
   Marshal.dump($game_system, file)
   Marshal.dump($game_switches, file)
   Marshal.dump($game_variables, file)
   Marshal.dump($game_self_switches, file)
   Marshal.dump($game_screen, file)
   Marshal.dump($game_actors, file)
   Marshal.dump($game_party, file)
   Marshal.dump($game_troop, file)
   Marshal.dump($game_map, file)
   Marshal.dump($game_player, file)
 end

 def read_save_data(file)
   characters = Marshal.load(file)
   Graphics.frame_count = Marshal.load(file)
   $game_system        = Marshal.load(file)
   $game_switches      = Marshal.load(file)
   $game_variables     = Marshal.load(file)
   $game_self_switches = Marshal.load(file)
   $game_screen        = Marshal.load(file)
   $game_actors        = Marshal.load(file)
   $game_party         = Marshal.load(file)
   $game_troop         = Marshal.load(file)
   $game_map           = Marshal.load(file)
   $game_player        = Marshal.load(file)
   if $game_system.magic_number != $data_system.magic_number
     $game_map.setup($game_map.map_id)
     $game_player.center($game_player.x, $game_player.y)
   end
   $game_party.refresh
 end
end

#==============================================================================
# ** Scene_Save
#==============================================================================

class Scene_Save < Scene_File
 def initialize(from_name=false)
   @from_name = from_name
   if @from_name == false
     $save_variable = ""
   end
 end

 def main
   a1 = "Create new file"
   a2 = "Overwrite file"
   a3 = "Cancel"
   @command_window = Window_Command.new(300, [a1, a2, a3])
   @command_window.index = 0
   @continue_enabled = false
   if Dir.get_save_files(Save_Module.folder).size > 0
     @continue_enabled = true
   end
   unless @continue_enabled
     @command_window.disable_item(1)
   end
   b1 = "This file already exists!"
   b2 = "Overwrite"
   b3 = "Cancel"
   @confirm_window = Window_Confirm.new(b1, b2, b3)
   @confirm_window.x = 20
   @confirm_window.y = 160
   @confirm_window.visible = false
   @confirm_window.active = false
   @save_window = Window_File.new
   @save_window.y = 128
   @save_window.visible = false
   @save_window.active = false
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     if $scene != self
       break
     end
   end
   Graphics.freeze
   @command_window.dispose
   @confirm_window.dispose
   @save_window.dispose
 end

 def update
   @command_window.update
   @confirm_window.update
   @save_window.update
   if @from_name == true
     @from_name = false
     filename = make_filename($save_variable)
     if FileTest.exist?(filename)
       to_confirm
       return
     end
     $game_temp.playing_file = $save_variable
     create_file(filename)
     return
   end
   if @command_window.active
     update_command
     return
   end
   if @confirm_window.active
     update_confirm
     return
   end
   if @save_window.active
     update_save
     return
   end
 end

 def update_command
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     if $game_temp.save_calling
       $game_temp.save_calling = false
       $scene = Scene_Map.new
       return
     end
     $scene = Scene_Menu.new(4)
   end
   if Input.trigger?(Input::C)
     case @command_window.index
     when 0 # "Create new file"
       $game_system.se_play($data_system.decision_se)
       $scene = Scene_Variable_Name.new
     when 1 # "Overwrite file"
       if Dir.get_save_files(Save_Module.folder).size == 0
         $game_system.se_play($data_system.buzzer_se)
         return
       end
       $game_system.se_play($data_system.decision_se)
       # save_files = Dir.get_save_files(Save_Module.folder)
       @save_window.refresh
       @command_window.active = false
       @confirm_window.active = false
       @save_window.visible = true
       @save_window.active = true
     when 2 # "Cancel"
       $game_system.se_play($data_system.cancel_se)
       if $game_temp.save_calling
         $game_temp.save_calling = false
         $scene = Scene_Map.new
         return
       end
       $scene = Scene_Menu.new(4)
     end
   end
 end

 def update_confirm
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     @command_window.index = 0
     @command_window.active = true
     @confirm_window.visible = false
     @confirm_window.active = false
     return
   end
   if Input.trigger?(Input::C)
     case @confirm_window.index
     when 0 # Yes
       filename = make_filename($save_variable)
       $game_temp.playing_file = $save_variable
       create_file(filename)
     when 1 # No
       $game_system.se_play($data_system.cancel_se)
       @command_window.index = 0
       @command_window.active = true
       @confirm_window.visible = false
       @confirm_window.active = false
     end
   end
 end

 def update_save
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     @command_window.active = true
     @save_window.visible = false
     @save_window.active = false
     return
   end
   if Input.trigger?(Input::C)
     $save_variable = @save_window.item
     to_confirm
   end
 end

 def to_confirm
   $game_system.se_play($data_system.cursor_se)
   @command_window.active = false
   @save_window.active = false
   @save_window.visible = false
   @confirm_window.visible = true
   @confirm_window.active = true
 end

 def create_file(filename)
   $game_system.se_play($data_system.save_se)
   file = File.open(filename, "wb")
   write_save_data(file)
   file.close
   if $game_temp.save_calling
     $game_temp.save_calling = false
     $scene = Scene_Map.new
     return
   end
   $scene = Scene_Menu.new(4)
 end
end

#==============================================================================
# ** Scene_Load
#==============================================================================

class Scene_Load < Scene_File
 def initialize
   $game_temp = Game_Temp.new
 end

 def main
   a1 = "Load file"
   a2 = "Cancel"
   @command_window = Window_Command.new(300, [a1, a2])
   @command_window.index = 0
   @load_window = Window_File.new
   @load_window.y = 128
   @load_window.visible = false
   @load_window.active = false
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     if $scene != self
       break
     end
   end
   Graphics.freeze
   @command_window.dispose
   @load_window.dispose
 end

 def update
   @command_window.update
   @load_window.update
   if @command_window.active
     update_command
     return
   end
   if @load_window.active
     update_load
     return
   end
 end

 def update_command
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     $scene = Scene_Title.new
     return
   end
   if Input.trigger?(Input::C)
     case @command_window.index
     when 0 # "Load file"
       $game_system.se_play($data_system.decision_se)
       # save_files = Dir.get_save_files(Save_Module.folder)
       @load_window.refresh
       @command_window.active = false
       @load_window.visible = true
       @load_window.active = true
     when 1 # "Cancel"
       $game_system.se_play($data_system.cancel_se)
       $scene = Scene_Title.new
     end
   end
 end

 def update_load
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     @command_window.active = true
     @load_window.visible = false
     @load_window.active = false
     return
   end
   if Input.trigger?(Input::C)
     $game_temp.playing_file = @load_window.item
     filename = make_filename(@load_window.item)
     load_file(filename)
   end
 end

 def load_file(filename)
   $game_system.se_play($data_system.load_se)
   file = File.open(filename, "rb")
   read_save_data(file)
   file.close
   $game_system.bgm_play($game_system.playing_bgm)
   $game_system.bgs_play($game_system.playing_bgs)
   $game_map.update
   $scene = Scene_Map.new
 end
end


Eron made an addon for this script which uses the default interface instead of the new. Place it under mine if you want to use that.
Spoiler: ShowHide

#==============================================================================
# [XP] Default Interface for Wecoc's Dynamic File System
#------------------------------------------------------------------------------
# by: Eron
#==============================================================================

module Save_Module
 FW_FIT = 4 # Number of file windows that fit on screen
 FW_MIN = 4 # Minimum number of file windows. It should be the same as FW_FIT
 FW_MAX = 4 # Maximum number of save files. Set it nil to have no limits.
 EMPTY = "- Empty -" # Window's name when empty
end

class Dir
 def Dir.save_files_by(sym)
   array = []
   Dir.get_save_files(Save_Module.folder).each do |last|
     file = File.open("#{Save_Module.folder}/#{last}.rxdata", "r")
     array.push [last, file.send(sym)]
   end
   array.sort! {|a, b| b[1] <=> a[1] }
   return array
 end

 def Dir.last_file_played
   files = Dir.save_files_by(:mtime)
   return files[0][0]
 end
end

#==============================================================================
# ** Window_SaveFile
#==============================================================================

class Window_SaveFile < Window_Base

 attr_reader :file_index
 attr_reader :filename
 attr_reader :file_exist

 def initialize(file_index, filename, file_exist=true)
   super(0, 0, 640, (480 - 64) / Save_Module::FW_FIT)
   self.contents = Bitmap.new(width - 32, height - 32)
   @file_index = file_index
   @filename = filename
   @file_exist = file_exist
   @time_stamp = Time.at(0)
   @name_width = 0
   if @file_exist
     file = File.open("#{Save_Module.folder}/#{filename}.rxdata", "r")
     @time_stamp = file.mtime
     @characters         = Marshal.load(file)
     @frame_count        = Marshal.load(file)
     @game_system        = Marshal.load(file)
     @game_switches      = Marshal.load(file)
     @game_variables     = Marshal.load(file)
     @game_self_switches = Marshal.load(file)
     @game_screen        = Marshal.load(file)
     @game_actors        = Marshal.load(file)
     @game_party         = Marshal.load(file)
     @game_troop         = Marshal.load(file)
     @game_map           = Marshal.load(file)
     @game_player        = Marshal.load(file)
     @total_sec = @frame_count / Graphics.frame_rate
     file.close
   end
   refresh
   @selected = false
 end

 def refresh
   self.contents.clear
   self.contents.font.color = normal_color
   if @filename == Save_Module::EMPTY
     self.contents.font.color = disabled_color
   end
   name = @filename
   self.contents.draw_text(4, 0, 600, 32, name)
   @name_width = contents.text_size(name).width
   if @file_exist
     for i in 0...@characters.size
       # Actor's graphic
       bitmap = RPG::Cache.character(@characters[i][0], @characters[i][1])
       cw = bitmap.rect.width / 4
       ch = bitmap.rect.height / 4
       src_rect = Rect.new(0, 0, cw, ch)
       x = 300 - @characters.size * 32 + i * 64 - cw / 2
       self.contents.blt(x, 68 - ch, bitmap, src_rect)
       ## Actor's name
       # draw_actor_name(@game_party.actors[i], x - 16, 8)
       ## Actor's level
       # draw_actor_level(@game_party.actors[i], x - 16, 24)
       ## Actor's states
       # draw_actor_state(@game_party.actors[i], x - 16, 48)
     end
     # Draw play time
     hour = @total_sec / 60 / 60
     min = @total_sec / 60 % 60
     sec = @total_sec % 60
     time_string = sprintf("%02d:%02d:%02d", hour, min, sec)
     self.contents.font.color = normal_color
     self.contents.draw_text(4, 8, 600, 32, time_string, 2)
     # Draw timestamp
     self.contents.font.color = normal_color
     time_string = @time_stamp.strftime("%Y/%m/%d %H:%M")
     self.contents.draw_text(4, 40, 600, 32, time_string, 2)
     ## Gold
     # cx = contents.text_size($data_system.words.gold).width
     # self.contents.font.color = normal_color
     # self.contents.draw_text(4, 8, 120-cx-2, 32, @game_party.gold.to_s, 2)
     # self.contents.font.color = system_color
     # self.contents.draw_text(124-cx, 8, cx, 32, $data_system.words.gold, 2)
     ## Variable
     # self.contents.font.color = system_color
     # self.contents.draw_text(4, 8, 120, 32, "Capítulo")
     # self.contents.font.color = normal_color
     # self.contents.draw_text(100, 8, 48, 32, @game_variables[1].to_s)
     ## Map name
     # self.contents.font.color = normal_color
     # self.contents.draw_text(4, 40, 320, 32, @game_map.map_name)
   end
 end
end

class Game_Map
attr_reader  :map_id
 def map_name
   @mpn = load_data("Data/MapInfos.rxdata")
 return @mpn[@map_id].name
 end
end

#==============================================================================
# ** Scene_File
#==============================================================================

class Scene_File
 def refresh
   if @savefile_windows != nil
     for i in @savefile_windows
       i.dispose
     end
   end
   @savefile_windows = []
   save_files = Dir.save_files_by(:mtime)
   size = save_files.size
   for i in 0...size
     @savefile_windows.push(Window_SaveFile.new(i, save_files[i][0]))
   end
   if self.is_a?(Scene_Save)
     if Save_Module::FW_MAX == nil or size < Save_Module::FW_MAX
       @savefile_windows.push(Window_SaveFile.new(size, "New File", false))
     end
   end
   loop do
     if @savefile_windows.size < Save_Module::FW_MIN
       size = @savefile_windows.size
       empty = Save_Module::EMPTY
       @savefile_windows.push(Window_SaveFile.new(size, empty, false))
     else
       break
     end
   end
   @file_index = 0
   @first_window = 0
   @savefile_windows[@file_index].selected = true
   window_refresh
 end
 
 def window_refresh
   for window in 0...@savefile_windows.size
     @savefile_windows[window].y = 64
     @savefile_windows[window].visible = false
     window_index = (window - @first_window)
     if (0..3).include?(window_index)
       height = (480 - 64) / Save_Module::FW_FIT
       @savefile_windows[window].y = 64 + window_index * height
       @savefile_windows[window].visible = true
     end
   end
 end
end

#==============================================================================
# ** Scene_Save
#==============================================================================

class Scene_Save < Scene_File
 def main
   @help_window = Window_Help.new
   @help_window.set_text("Which file would you like to save to?")
   refresh
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     if $scene != self
       break
     end
   end
   Graphics.freeze
   @help_window.dispose
   for i in @savefile_windows
     i.dispose
   end
 end

 def update
   @help_window.update
   for i in @savefile_windows
     i.update
   end

   if @from_name == true
     @from_name = false
     filename = make_filename($save_variable)
     if FileTest.exist?(filename)
       $game_system.se_play($data_system.buzzer_se)
       return
     end
     $game_temp.playing_file = $save_variable
     create_file(filename)
     return
   end

   if Input.trigger?(Input::C)
     if @savefile_windows[@file_index].filename == Save_Module::EMPTY
       $game_system.se_play($data_system.buzzer_se)
       return
     end
     $game_system.se_play($data_system.decision_se)
     if @savefile_windows[@file_index].file_exist == false
       $scene = Scene_Variable_Name.new
       return
     else
       filename = make_filename(@savefile_windows[@file_index].filename)
       $game_temp.playing_file = @savefile_windows[@file_index].filename
       create_file(filename)
       return
     end
   end

   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     if $game_temp.save_calling
       $game_temp.save_calling = false
       $scene = Scene_Map.new
       return
     end
     $scene = Scene_Menu.new(4)
   end

   max_files = @savefile_windows.size

   if Input.repeat?(Input::DOWN)
     if Input.trigger?(Input::DOWN) or @file_index < max_files - 1
       $game_system.se_play($data_system.cursor_se)
       @savefile_windows[@file_index].selected = false
       @file_index += 1
       if @file_index == max_files
         @file_index = 0
         @first_window = 0
       elsif @file_index - @first_window > (Save_Module::FW_FIT - 1)
         @first_window += 1
       end
       window_refresh
       @savefile_windows[@file_index].selected = true
       return
     end
   end

   if Input.repeat?(Input::UP)
     if Input.trigger?(Input::UP) or @file_index > 0
       $game_system.se_play($data_system.cursor_se)
       @savefile_windows[@file_index].selected = false
       @file_index -= 1
       if @file_index == -1
         @file_index = max_files - 1
         @first_window = @file_index - (Save_Module::FW_FIT - 1)
       elsif @first_window - @file_index > 0
         @first_window -= 1
       end
       window_refresh
       @savefile_windows[@file_index].selected = true
       return
     end
   end
 end

 def create_file(filename)
   $game_system.se_play($data_system.save_se)
   file = File.open(filename, "wb")
   write_save_data(file)
   file.close
   if $game_temp.save_calling
     $game_temp.save_calling = false
     $scene = Scene_Map.new
     return
   end
   refresh
 end
end

#==============================================================================
# ** Scene_Load
#==============================================================================

class Scene_Load < Scene_File
 def initialize
   $game_temp = Game_Temp.new
 end

 def main
   @help_window = Window_Help.new
   @help_window.set_text("Which file would you like to load?")
   refresh
   Graphics.transition
   loop do
     Graphics.update
     Input.update
     update
     if $scene != self
       break
     end
   end
   Graphics.freeze
   @help_window.dispose
   for i in @savefile_windows
     i.dispose
   end
 end

 def update
   @help_window.update
   for i in @savefile_windows
     i.update
   end

   if Input.trigger?(Input::C)
     if @savefile_windows[@file_index].filename == Save_Module::EMPTY
       $game_system.se_play($data_system.buzzer_se)
       return
     end
     $game_system.se_play($data_system.decision_se)
     $game_temp.playing_file = @savefile_windows[@file_index].filename
     filename = make_filename(@savefile_windows[@file_index].filename)
     load_file(filename)
   end
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     $scene = Scene_Title.new
   end

   max_files = @savefile_windows.size

   if Input.repeat?(Input::DOWN)
     if Input.trigger?(Input::DOWN) or @file_index < max_files - 1
       $game_system.se_play($data_system.cursor_se)
       @savefile_windows[@file_index].selected = false
       @file_index += 1
       if @file_index == max_files
         @file_index = 0
         @first_window = 0
       elsif @file_index - @first_window > (Save_Module::FW_FIT - 1)
         @first_window += 1
       end
       window_refresh
       @savefile_windows[@file_index].selected = true
       return
     end
   end

   if Input.repeat?(Input::UP)
     if Input.trigger?(Input::UP) or @file_index > 0
       $game_system.se_play($data_system.cursor_se)
       @savefile_windows[@file_index].selected = false
       @file_index -= 1
       if @file_index == -1
         @file_index = max_files - 1
         @first_window = @file_index - (Save_Module::FW_FIT - 1)
       elsif @first_window - @file_index > 0
         @first_window -= 1
       end
       window_refresh
       @savefile_windows[@file_index].selected = true
       return
     end
   end
 end
end




Instructions

The script uses a new folder to save all the files inside. If it does not exist it will be created automatically. If you have files already, you will have to move them to the new folder.
To change the folder name, find on the very start of the script this line and change it there:
FOLDER = "Save"

If you name it "" or nil, the files will be saved in the game's folder as always.



Compatibility

Not tested. If there is any problem you can contact me.
I had to rewrite the method :main of Scene_Title, so if you use a modification of the Title beware with this. Practically this is the only incompatibility that can give you problems if you are not careful.


Credits and Thanks


  • Wecoc - The WDSF script basis

  • Eron - Default Interface Script


KK20


Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!