Код:
#==============================================================================
# ** 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
Социальные закладки