Новая система сохранений
Автор Fantasist
Версия 1.4.2
На русский язык перевел Devillion (немного криво)

Chaos Project Save Layout - скрипт, который обновляет стандартную систему сохранений\загрузки игры, делая ее более удобной и легко настраиваемой.

- Настраиваемое количество сохранений
- Выбор папки, куда сохраняются файлы сохранений
- Система глав и локаций

И многое другое!

Вставить над Main

Скрипт:

Код:
#==============================================================================
# ** Chaos Project Save Layout
#------------------------------------------------------------------------------
# by Fantasist
# Версия 1.4.2
# 24-Feb-2011
# Перевел Devillion
#------------------------------------------------------------------------------
# История изменений:
#
#   1.0 - Первая версия
#   1.1 - Оптимизация кода
#   1.2 - Некоторые новые возможности
#   1.3 - Более быстрая загрузка сцены
#   1.4 - Добавлено имя локации и система глав
#   1.4.1 - Теперь перезапись настроена по умолчанию
#   1.4.2 - Новые возможности (цветной текст в списке файлов)
#------------------------------------------------------------------------------
# Описание:
#     Этот скрипт заменяет стандартную сцену сохранения\загрузки игры
#
#   Особенности проекта:
#    - Схема
#    - Окно подтверждения перезаписи (опционально)
#    - Обнаруживает и использует виндскин из файла сохранения(полезно с другими
#      скриптами,которые вносят изменения в виндскин)
#    - Обнаруживает и использует шрифт с файлов сохранений
#    - Предотвращение сбоев и окно "Сохраненый файл поврежден"     
#    - Совместимость с DREAM для сохраненых файлов
#    - Имя локации (опционально)
#
#   Дополнительные возможности:
#    - Система глав (опционально)
#    - Настраиваемое количество слотов для сохранения, изменение имени файла
#      сохранения,изменение расширения сохраненного файла,изменение места
#      сохранения игры 
#    - Настраиваемый текст сцены сохранения\загрузки 
#    - Указывает что файл существует красочным цветом (опционально)
#------------------------------------------------------------------------------
# Совместимость:
#
#   - Может быть несовместима с другими системами сохранения\загрузки игры
#   - Совместимость с 'Ultimate Font Override' из Tons of Addons,
#     'Storm Tronics CMS' и 'DREAM for Savefiles' by Blizzard
#------------------------------------------------------------------------------
# Установка: Поместить этот скрипт над Main и под Scene_Load.            
#
# Настройка:

module CPSL
  
#============================================================
# Main Config Start
#============================================================
  
  Save_number = 8     # Количество слотов для сохранения
  Save_path = ''      # Путь, где находятся файлы сохранения(Например:'Saves/')
  Save_name = 'Save'  # Имя файла сохранения
  Save_ext = 'rxdata' # Расширение сохранений
  
  Confirm_Overwrite = true  # Выключение\выключение окна "Перезаписать игру?"
  Confirm_Overwrite_Words = 'Перезаписать игру?'  # В строке будет отображаться
  Confirm_Overwrite_default = 1 # Выбор по умолчанию в окне перезаписи
                                # 0: Да, 1: Нет
  
  Chapter = true  # Включение\выключение системы глав
  Location = true  # Включение\выключение имени локации
  
  File_name = 'Файл '  # Название файла сохранения (No. 1, No. 2, и т.д.)
  No_file_text = 'Нет сохраненных игр'  # Текст "Нет сохраненных игр"
  Corrupted_file_text = 'Поврежденный файл'  # Текст "Поврежденный файл"
  Load_Help_Text = 'Какую игру вы хотите загрузить?' # Текст вопроса загрузки
  Save_Help_Text = 'Куда вы хотите сохранить игру?'   # Текст вопроса сохранения
  
  Show_File_Exists = true # Включить\выключить показ файлов, если есть в списке
  File_Exist_Color = Color.new(255, 255, 255) # Цвет текста если имеется сохр.
  File_Empty_Color = Color.new(128, 128, 128) # Цвет текста если нет сохр.
  File_Corrupt_Color = Color.new(255, 0, 0) # Цвет текста если файл поврежден
  module_function
  
  def chapter(gs)
    ch = case gs.chapter
    #=============Настройка системы глав=======================
    # Чтобы указать часть игры,вызовите скрипт в "Команде событий"
    #                 $game_system.chapter = <number>
    #
    when 1 then '1 Глава'
    when 2 then '2 Глава'
    # чтобы добавить еще одну главу,скопируйте эту строку
    # и измените число и название главы
    #=====================================================
    else '---'
    end
    return [gs.chapter, ch]
  end
  
#===========================================================================
# Основная конфигурация завершена (см. ниже для дополнительной конфигурации)
#===========================================================================
  
  
  def set_fontsize(font)
    size = case font
    #=============Изменение размера текста=======================
    # Это размер шрифта, который будет отображаться в окне информации о файле.
    # Это было сделано потому, что я решил сделать шрифт layout (21)
    # Может не работать со шрифтами кроме Arial. Если вы пользуетесь другим
    # Шрифтом и он выглядит неправильно,добавьте его в список.
    when 'Impact' then 24
    when 'Comic Sans MS' then 24
    when 'Brush Script' then 24
    # чтобы добавить другой шрифт,скопируйте эту строку
    # и напишите имя шрифта и размер
    #=====================================================
    else 21
    end
    return size
  end

#============================================================
# Конец настройки
#============================================================

  
  def make_savename(file_index)
    return Save_path + Save_name + "#{file_index + 1}." + Save_ext
  end
  
end
#------------------------------------------------------------------------------
# Вопросы:
#
#   Здесь все просто и нет вопросы не должны возникнуть.
#
#------------------------------------------------------------------------------
# Кредиты: За фантастическое оформление
# Благодарности: Blizzard(и его игре Chaos Project) за верстку и вдохновение
#         Sase за указание на окно с вопросом о перезаписи, и
#         IserLuick за постановку дополнительных функций.
#------------------------------------------------------------------------------
# Примечание:
# Если у вас будут вопросы или проблемы,вы можете найти меня здесь:
#
# www.chaos-project.com
#
# Пользуйтесь ^_^
#==============================================================================

#==============================================================================
# ** Bitmap
#==============================================================================

class Bitmap
  
  def draw_load_bar(num)
    o = 160
    w, h = self.width - 32, 12
    bh = 2
    c = num == 100 ? Color.new(0, 255, 0, o) : Color.new(255, 0, 0, o)
    fill_rect(16 + 0, self.height - bh*h, w, h, Color.new(255, 255, 255, o))
    fill_rect(16 + 1, self.height - bh*h + 1, w-2, h-2, Color.new(0, 0, 0, o))
    fill_rect(16 + 2, self.height - bh*h + 2, (w-4)*num/100, h-4, c)
  end
  
end

#==============================================================================
# ** Loading_Bar
#==============================================================================

class Loading_Bar < Sprite
  
  def initialize
    w, h = 200, 80
    super
    self.ox, self.oy = w/2, h/2
    self.bitmap = Bitmap.new(w, h)
    self.bitmap.fill_rect(self.bitmap.rect, Color.new(0, 0, 0, 160))
    self.z = 999
    self.bitmap.draw_text(0, 0, w, 32, 'Загрузка...', 1)
    self.bitmap.draw_load_bar(0)
  end
  
  def refresh(num=0)
    self.bitmap.fill_rect(0, 0, self.bitmap.width, 32, Color.new(0, 0, 0, 160))
    txt = num == 100 ? 'Выполнено!' : 'Загрузка...'
    self.bitmap.draw_text(0, 0, self.bitmap.width, 32, txt, 1)
    self.bitmap.draw_load_bar(num)
  end
  
end

#==============================================================================
# ** Window_Prompt
#==============================================================================

class Window_Prompt < Window_Base
  
  attr_reader :index
  
  def initialize(txt, mode=0, index=0)
    @txt, @mode = txt, mode
    width = [text_width(txt) + 32, 220].max
    height = 64 + mode * 64
    super(320 - width/2, 240 - height/2, width, height)
    self.contents = Bitmap.new(self.width - 32, self.height - 32)
    bmp = Bitmap.new(192, 128)
    bmp.fill_rect(0, 0, 128, 128, Color.new(0, 0, 0, 200))
    bmp.fill_rect(128, 64, 32, 32, Color.new(255, 0, 0, 200))
    self.windowskin = bmp
    refresh
    @index = @mode > 0 ? index : -1
  end
  
  def text_width(text)
    dummy = Bitmap.new(640, 64)
    w = dummy.text_size(text).width
    dummy.dispose
    return w
  end
  
  def reset(txt, mode=0, index=0)
    @txt = txt unless txt == nil
    @mode = mode
    @index = @mode > 0 ? index : -1
    self.contents.dispose
    width = [text_width(txt) + 32, 300].max
    self.width, self.height = width, 64 + mode * 64
    self.x, self.y = 320 - self.width/2, 240 - self.height/2
    self.contents = Bitmap.new(self.width - 32, self.height - 32)
    refresh
    update_cursor_rect
  end
  
  def refresh
    self.contents.clear
    self.contents.draw_text(0, 0, self.width - 32, 32, @txt, 1)
    if @mode > 0
      self.contents.draw_text(self.width/2 - 16 - 34, 32, 68, 32, 'Да', 1)
      self.contents.draw_text(self.width/2 - 16 - 34, 64, 68, 32, 'Нет', 1)
    end
  end
  
  def index=(index)
    @index = index
    update_cursor_rect
  end
  
  def update_cursor_rect
    if @index < 0
      self.cursor_rect.empty
      return
    end
    cursor_width = self.contents.text_size('  Да  ').width
    x = (self.width - cursor_width)/2 - 16
    y = 32 + @index * 32
    self.cursor_rect.set(x, y, cursor_width, 32)
  end
  
  def update
    super
    if @mode > 0
      if self.active && @index >= 0
        if Input.repeat?(Input::DOWN)
          $game_system.se_play($data_system.cursor_se)
          @index = (@index + 1) % 2
        elsif Input.repeat?(Input::UP)
          $game_system.se_play($data_system.cursor_se)
          @index = (@index - 1) % 2
        end
      end
      update_cursor_rect
    end
  end
  
end

#==============================================================================
# ** Window_FileList
#==============================================================================

class Window_FileList < Window_Selectable
  
  def initialize
    super(0, 64, 98, 416)
    list = []
    (1..CPSL::Save_number).each {|i| list.push("#{CPSL::File_name}#{i}")}
    @commands = list
    @item_max = list.size
    @ch = list.size < 12 ? (self.height - 32) / list.size : 32
    self.contents.dispose if self.contents
    self.contents = Bitmap.new(self.width - 32, list.size < 12 ? 416-32 : list.size * 32)
    refresh
  end
  
  def refresh
    self.contents.clear
    (0...@item_max).each {|i|
    if CPSL::Show_File_Exists
      color = FileTest.exist?(CPSL.make_savename(i)) ? CPSL::File_Exist_Color : CPSL::File_Empty_Color
    else
      color = normal_color
    end
    draw_item(i, color)}
  end
  
  def draw_item(index, color)
    self.contents.font.color = color
    rect = Rect.new(4, @ch * index, self.contents.width - 8, @ch)
    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
    self.contents.draw_text(rect, @commands[index], @commands.size > 9 ? 0 : 1)
  end
  
  alias fant_cpsl_list_upd_cursor_rect update_cursor_rect
  def update_cursor_rect
    fant_cpsl_list_upd_cursor_rect
    cursor_width = self.width / @column_max - 32
    x = @index % @column_max * (cursor_width + 32)
    y = @index / @column_max * @ch - self.oy + (@ch-32)/2
    self.cursor_rect.set(x, y, cursor_width, 32)
  end
  
end

#==============================================================================
# ** Window_FileInfo
#==============================================================================

class Window_FileInfo < Window_Base
  
  attr_reader :index
  
  def initialize(file_index=0)
    super(98, 64, 542, 416)
    self.contents = Bitmap.new(width - 32, height - 32)
    self.contents.font.size = 21
    @index = -2
    @bar = Loading_Bar.new
    @bar.x = self.x + self.width / 2
    @bar.y = self.y + self.height / 2 - 32
    @bar.visible = false
    @save_data = []
    reload(file_index)
  end
  
  def reload(index)
    return if @index == index
    @index = index
    self.visible = false
    if @save_data[index] == nil
      filename = CPSL.make_savename(index)
      file_exist = FileTest.exist?(filename)
      if file_exist
        begin
          file = File.open(filename, 'r')
          ts = file.mtime
          if (defined? DREAM) && Required_DREAM_Version >= 4.1
            @bar.refresh(0)
            @bar.visible = true
            Graphics.transition(10)
            gs, gs, gs, gp, gp, gp, gm = DREAM.data(file)
            @bar.refresh(100)
            Graphics.update
            Graphics.freeze
            @bar.visible = false
            Graphics.transition(10)
          else
            @bar.refresh(0)
            @bar.visible = true
            Graphics.transition(10)
            3.times {|i| gs = Marshal.load(file); @bar.refresh(i*100/11); Graphics.update}
            6.times {|i| gp = Marshal.load(file); @bar.refresh((i+3)*100/11); Graphics.update}
            2.times {|i| gm = Marshal.load(file); @bar.refresh((i+9)*100/11); Graphics.update}
            @bar.refresh(100)
            Graphics.update
            Graphics.freeze
            @bar.visible =false
            Graphics.transition(10)
          end
          file.close
          Graphics.freeze
        rescue
          file.close
          @bar.visible = false
          ts = gs = gp = gm = 'Плохой файл'
          $scene.list_win.draw_item(index, CPSL::File_Corrupt_Color)
        end          
      else
        ts = gs = gp = gm = nil
      end
      @save_data[index] = [ts, gs, gp, gm]
    end
    @time_stamp, @game_system, @game_party, @game_map = @save_data[index][0],
      @save_data[index][1], @save_data[index][2], @save_data[index][3]
    self.visible = true
    refresh
    Graphics.transition(5)
  end
  
  def refresh
    self.contents.clear
    self.contents.font.name = @game_system.fontname rescue 'Arial'
    self.contents.font.size = CPSL.set_fontsize(self.contents.font.name)
    self.windowskin = RPG::Cache.windowskin(@game_system.windowskin_name) rescue nil
    if @game_party == nil
      self.contents.font.color = normal_color
      draw_text_center(CPSL::No_file_text)
    elsif @time_stamp == 'Плохой файл'
      self.contents.font.color = Color.new(255, 0, 0)
      draw_text_center(CPSL::Corrupted_file_text)
    else
      mtime = @time_stamp
      date = mtime.strftime("%d-%b-%Y")
      time = mtime.strftime("%I:%M:%S %p")
      self.contents.font.color = system_color
      y = !(CPSL::Chapter || CPSL::Location) ? self.contents.height-54 : 0
      self.contents.draw_text(0, y + 0, self.contents.width - 8, 32, time, 2)
      self.contents.draw_text(0, y + 32, self.contents.width - 8, 22, date, 2)
      self.contents.font.color = normal_color
      if CPSL::Chapter
        y = CPSL::Location ? 0 : 14
        chapter = CPSL.chapter(@game_system)
        chapter_text = "Часть #{chapter[0]}: #{chapter[1]}"
        self.contents.draw_text(0, y, 502, 32, chapter_text)
      end
      if CPSL::Location
        y = CPSL::Chapter ? 28 : 14
        self.contents.draw_text(0, y, 502, 32, 'Локация: ' + $map_names[@game_map.map_id])
      end
      @game_party.actors.each_index {|i|
        x = 64
        y = (!(CPSL::Chapter || CPSL::Location) ? 8 : 48) + i * 82
        actor = @game_party.actors[i]
        
        draw_actor_graphic(actor, x - 24, y + 86)
        draw_actor_name(actor, 0, y + 12, 82, 1)
        
        draw_actor_level(actor, x + 28, y + 12)
        draw_actor_state(actor, x + 28 + 64, y + 12)
        draw_actor_exp(actor, x + 28, y + 64 - 18)
        
        draw_actor_hp(actor, x + 224, y + 12)
        draw_actor_sp(actor, x + 224, y + 64 - 18)
      }
    end
  end
  
  def draw_text_center(txt)
    self.contents.draw_text(0, (self.height-32)/2 - 16, self.width - 32, 32, txt, 1)
  end
  
  def draw_text_outline(x, y, w, h, t, a=0)
    original_color = self.contents.font.color.clone
    self.contents.font.color = Color.new(0, 0, 0)
    self.contents.draw_text(x-1, y-1, w, h, t, a)
    self.contents.draw_text(x-1, y+1, w, h, t, a)
    self.contents.draw_text(x+1, y-1, w, h, t, a)
    self.contents.draw_text(x+1, y+1, w, h, t, a)
    self.contents.font.color = original_color
    self.contents.draw_text(x, y, w, h, t, a)
  end
  
  def draw_actor_name(actor, x, y, width=120, align=0)
    self.contents.font.color = normal_color
    self.contents.draw_text(x, y, width, 32, actor.name, align)
  end
  
  def dispose
    super
    @save_data = nil
    @bar.bitmap.dispose
    @bar.dispose
  end
  
end

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

class Scene_File
  
  attr_reader :list_win
  
  def initialize(help_text)
    @help_text = help_text
  end
  
  def main
    if $scene.is_a?(Scene_Load)
      text = CPSL::Load_Help_Text
    elsif $scene.is_a?(Scene_Save)
      text = CPSL::Save_Help_Text
    else
      text = @help_text
    end
    @help_text = text
    $game_temp.last_file_index = 0
    latest_time = Time.at(0)
    (0...CPSL::Save_number).each {|i|
      filename = make_filename(i)
      if FileTest.exist?(filename)
        file = File.open(filename, "r")
        if file.mtime > latest_time
          latest_time = file.mtime
          $game_temp.last_file_index = i
        end
        file.close
      end
    }
    @help_window = Window_Help.new
    @help_window.set_text(@help_text)
    @list_win = Window_FileList.new
    @list_win.index = $game_temp.last_file_index
    @info_win = Window_FileInfo.new(@list_win.index)
    @confirm_win = Window_Prompt.new(CPSL::Confirm_Overwrite_Words, 1)
    @confirm_win.visible = @confirm_win.active = false
    @confirm_win.z = @info_win.z + 10
    Graphics.transition
    loop {
      Graphics.update
      Input.update
      update
      if $scene != self
        break
      end
    }
    Graphics.freeze
    @help_window.dispose
    @list_win.dispose
    @info_win.dispose
    @confirm_win.dispose
  end
  
  def update
    @help_window.update
    if @list_win.active
      update_list
    elsif @confirm_win.active
      update_confirm
    end
  end
  
  def update_list
    @list_win.update
    if Input.trigger?(Input::C)
      if $scene.is_a?(Scene_Save) && CPSL::Confirm_Overwrite &&
        FileTest.exist?(make_filename(@list_win.index))
        @list_win.active = false
        @confirm_win.index = CPSL::Confirm_Overwrite_default
        @confirm_win.visible = @confirm_win.active = true
        $game_system.se_play($data_system.decision_se)
        return
      end
      on_decision(make_filename(@list_win.index))
      $game_temp.last_file_index = @list_win.index
    elsif Input.trigger?(Input::B)
      on_cancel
    elsif Input.repeat?(Input::UP)
      @info_win.reload(@list_win.index)
    elsif Input.repeat?(Input::DOWN)
      @info_win.reload(@list_win.index)
    end
  end
  
  def update_confirm
    @confirm_win.update
    if Input.trigger?(Input::C)
      if @confirm_win.index == 0
        on_decision(make_filename(@list_win.index))
        $game_temp.last_file_index = @list_win.index
      end
      $game_system.se_play($data_system.cancel_se) if @confirm_win.index == 1
      @confirm_win.visible = @confirm_win.active = false
      @list_win.active = true
    elsif Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @confirm_win.visible = @confirm_win.active = false
      @list_win.active = true
    end
  end
  
  def make_filename(index)
    CPSL.make_savename(index)
  end
  
end

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

class Scene_Title
  
  alias fant_cpsl_title_main main
  def main
    unless $map_names
      $map_names = load_data('Data/MapInfos.rxdata')
      $map_names.each_key {|key| $map_names[key] = $map_names[key].name}
    end
    fant_cpsl_title_main
  end
  
end

#==============================================================================
# ** Game_System
#==============================================================================

class Game_System
  attr_accessor :chapter
end
Untitled-1.jpgUntitled-2.jpgUntitled-3.jpg