#============================================================================
# 简易存档管理系统
#----------------------------------------------------------------------------
# By : RyanBern
#============================================================================
=begin
 
功能:把存档,读档,删档糅合到了一起,一个场景能实现三个功能。
档位增加到了6个。
注意,进行删档的时候不会有确认提示,会直接把档删了。如果要加确认提示的话,再联
系我吧。其实是我偷懒了。
 
脚本插入到Main前即可,没有对原始脚本改动,冲突可能性小。
需要手动改几个地方(如果对应行找不到就开一下搜索,在相应脚本内部搜即可)
 
1.Scene_Title,48行,for i in 0..3改成for i in 0..5
2.Scene_Title,157行,$scene = Scene_Load.new改成$scene = Scene_File_Manager.new(true)
3.Scene_Map,224行,$scene = Scene_Save.new改成$scene = Scene_File_Manager.new
4.Scene_Menu,160行,$scene = Scene_Save.new改成$scene = Scene_File_Manager.new
 
不想要这个脚本的时候记得把上面几处都改成原来的样子。
 
=end
class Window_File < Window_Selectable
  def initialize
    super(0, 128, 640, 352)
    self.contents = Bitmap.new(width - 32, height - 32)
    @item_max = 6
    self.index = 0
    refresh
  end
  def refresh
    (0...6).each do |i|
      draw_item(i)
    end
  end
  def draw_item(index)
    filename = "Save#{index + 1}.rxdata"
    time_stamp = Time.at(0)
    file_exist = FileTest.exist?(filename)
    if file_exist
      file = File.open(filename, "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)
      total_sec = frame_count / Graphics.frame_rate
      file.close
    end
    x = 4
    y = index * 52
    self.contents.fill_rect(x, y, self.contents.width - 4, 52, Color.new(0,0,0,0))
    self.contents.font.size = 18
    # 描绘文件编号
    self.contents.font.color = normal_color
    name = "文件 #{index + 1}"
    self.contents.draw_text(4, y, 54, 32, name)
    @name_width = contents.text_size(name).width
    # 存档文件存在的情况下
    if file_exist
      # 描绘角色
      for i in 0...characters.size
        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)
        cx = 96 + i * (cw + 8)
        self.contents.blt(cx, y + (52 - ch) / 2, bitmap, src_rect)
      end
      # 描绘游戏时间
      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.size = 16
      self.contents.font.color = normal_color
      self.contents.draw_text(x + 444, y, 160, 24, time_string, 2)
      # 描绘时间标记
      self.contents.font.color = normal_color
      time_string = time_stamp.strftime("%Y/%m/%d %H:%M")
      self.contents.draw_text(x + 444, y + 24, 160, 24, time_string, 2)
    end
  end
  def update_cursor_rect
    if @index < 0
      self.cursor_rect.empty
    else
      self.cursor_rect.set(0, @index * 52, self.width - 32, 52)
    end
  end
end
 
class Window_File_Command < Window_Selectable
  def initialize
    super(0, 64, 640, 64)
    self.contents = Bitmap.new(width - 32, height - 32)
    @column_max = 3
    @item_max = 3
    self.index = 0
    @commands = ["存档", "读档", "档案管理"]
    refresh
  end
  def refresh
    (0...3).each do |i|
      draw_item(i)
    end
  end
  def draw_item(index, color = normal_color)
    x = 4 + index * width / @column_max
    y = 0
    w = self.contents.width / @column_max
    self.contents.fill_rect(x, y, w, 32, Color.new(0,0,0,0))
    self.contents.font.color = color
    self.contents.draw_text(x, y, w, 32, @commands[index])
  end
  def disable_item(index)
    draw_item(index, disabled_color)
  end
  def update_help
    texts = ["保存当前进度", "读取已有进度", "进行存档管理"]
    @help_window.set_text(texts[self.index])
  end
end
 
class Scene_File_Manager
  def initialize(save_disabled = false)
    @save_disabled = save_disabled
  end
  def main
    @dummy_window = Window_Base.new(0, 128, 640, 352)
    @help_window = Window_Help.new
    @file_window = Window_File.new
    @file_window.visible = false
    @file_window.active = false
    @command_window = Window_File_Command.new
    @command_window.help_window = @help_window
    if @save_disabled
      @command_window.disable_item(0)
    end
    Graphics.transition
    loop do
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    end
    Graphics.freeze
    @dummy_window.dispose
    @help_window.dispose
    @command_window.dispose
    @file_window.dispose
  end
  def update
    @file_window.update
    @command_window.update
    if @command_window.active
      update_command
      return
    end
    if @file_window.active
      update_file
    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
      elsif @save_disbled
        $scene = Scene_Title.new
      else
        $scene = Scene_Menu.new(5)
      end
      return
    end
    if Input.trigger?(Input::C)
      if @save_disabled && @command_window.index == 0
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      @command_window.active = false
      @dummy_window.visible = false
      @file_window.visible = true
      @file_window.active = true
      return
    end
  end
  def update_file
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @file_window.visible = false
      @file_window.active = false
      @dummy_window.visible = true
      @command_window.active = true
      return
    end
    if Input.trigger?(Input::C)
      filename = "Save#{@file_window.index + 1}.rxdata"
      case @command_window.index
      when 0
        $game_system.se_play($data_system.save_se)
        write_save_data(filename)
        if $game_temp.save_calling
          $game_temp.save_calling = false
          $scene = Scene_Map.new
        else
          $scene = Scene_Menu.new(5)
        end
        return
      when 1
        if FileTest.exist?(filename)
          $game_system.se_play($data_system.load_se)
          $game_temp = Game_Temp.new
          read_save_data(filename)
          $game_system.bgm_play($game_system.playing_bgm)
          $game_system.bgs_play($game_system.playing_bgs)
          $game_map.update
          $scene = Scene_Map.new
        else
          $game_system.se_play($data_system.buzzer_se)
        end
        return
      when 2
        if FileTest.exist?(filename)
          $game_system.se_play($data_system.decision_se)
          File.delete(filename)
          @file_window.draw_item(@file_window.index)
        else
          $game_system.se_play($data_system.buzzer_se)
        end
        return
      end
    end
  end
  def write_save_data(filename)
    file = File.open(filename, "wb")
    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)
    file.close
  end
  def read_save_data(filename)
    file = File.open(filename, "rb")
    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
    file.close
  end
end