AutoSave
Version 3.2
By A Crying Minister (WHITE-FLUTE)
Release Date 26/02/2008
Introduction
I thought that I want to share this,since there is no available AutoSave script for VX right now.It is a plug n play script,so there is no problem to use this script.
The script is obtained from this link:
http://www.whiteflute.org/wfrgss/Features
This script will create save file automatically after the ending of the battle and also moving to another map.It also will create back up data,thus reducing the risk of data loss.Also,the main script have an extra feature,which is if you choose to close the application,it will bring you to title screen,once.This feature is usefull in case if you accidently shut down the application.
Script
The family can have a break today!!
CODE
#===========================================================================
# ★ WF-RGSS Scripts ★
# 共通スクリプト(XP/VX両対応版)
# バージョン : rev-8 (2007-12-17)
# 作者 : A Crying Minister (WHITE-FLUTE)
# サポート先URI: http://www.whiteflute.org/wfrgss/
# ---------------------------------------------------------------------------
# 機能:
# ・このセクションより後ろのスクリプトでSyntaxError が発生しても
# 別の例外にすりかえられるため、詳細情報が削除されなくなります。
# ・シーンでリセットや例外が発生したとき、Bitmapなどを強制的に解放します。
# ・不用意なデバッグモードへの遷移を防止します。
# (元からデバッグモードの場合は問題ありません。)
# ・解放な必要なものも解放する機会を与えます。
# ---------------------------------------------------------------------------
# 影響:
# ・外部コマンド実行など一部の組み込み関数が未定義になります。
# ・例外 SyntaxError は作成できません。
# (※ ScriptSyntaxError にすりかえられます。)
# ・クラス変数や定数、グローバル変数に解放が必要なオブジェクトがある場合、
# リセットすると(解放されるため)不都合が発生することがあります。
# ---------------------------------------------------------------------------
# 設置場所 :一番最初のセクション( Game_Temp(XP)/モジュール(VX)よりも前 )
# 必要スクリプト:
# ・共通実行スクリプト
# 注意事項:
# 共通実行スクリプトをMainセクションに上書きして利用することを推奨します。
# ===========================================================================
module WFRGSS
# -------------------------------------------------------------------------
# ● 調整ポイント
# -------------------------------------------------------------------------
# 終了または異常時に自動的に解放処理を行うかを指定します。
# 解放の問題が発生する場合は、この値を false に設定してください。
AUTO_DISPOSER = false
# -------------------------------------------------------------------------
# 調整ポイント終わり
# -------------------------------------------------------------------------
end
# ---------------------------------------------------------------------------
# ● 例外定義
# ---------------------------------------------------------------------------
# 継承例外
class InheritanceError < Exception
end
# Mix-in 例外
class IncludeError < Exception
end
# 仮想クラス、メソッドの使用
class AbstractError < NoMethodError
end
# ◆ バグ検出
# バグ以外、絶対にありえない状態になったときに発生させてください。
# ※ バグ報告を行うためのものなので途中で破棄してはいけません。
class BugDetected < Exception
end
# ◆ 内部バグ報告用
# これは、WFRGSS でバグしかありえない状態に陥ったときに発生します。
# ※ バグ報告を行うためのものなので途中で破棄してはいけません。
class InternalBugDetected < BugDetected
end
# イベント階層が深すぎる場合
class EventDeepError < SystemStackError
end
# 初期化失敗
class InitializeError < TypeError
end
# アサーション失敗
class AssertionError < SecurityError
end
# ◆ 例外 Hangup
# ハングアップしたとみなされたときに投げられる例外。
# 深い階層からでは捉えられないことがあるため、注意が必要
# RPGVXにはありませんが、XPとの互換性を保つため、設定しています。
class Hangup < Exception
end
# ◆ 例外 Reset
# Graphics.update の呼び出し時にF12が押されていると投げられる例外。
# これがセクション外に出ると
# 最初のセクションから再び実行をやり直そうとします。
# この操作は、組み込みクラスのメソッドにて、
# alias や undef が使われていると
# 不具合の元になります。
class Reset < Exception
end
BEGIN {
# セキュリティ違反
class SecurityHazard < Exception
end
# RPGXP互換性のため
unless $TEST
$TEST = false
end
# ---------------------------------------------------------------------------
# ◆◆ デバッグモード阻止対策
# ---------------------------------------------------------------------------
# デバッグモード防止策
if defined? untrace_var
undef untrace_var
# デバッグモードでない場合、デバッグモードへの遷移を禁止する
proc = Proc.new {
if $DEBUG
$DEBUG = false
$TEST = false
$BTEST = false
raise(SecurityHazard ,"Insecure - debug flag can't be change.", caller(1))
end
}
trace_var( :$DEBUG , proc )
trace_var( :$-d , proc ) # $DEBUG の別名
proc = nil
# デバッグモードでない場合、デバッグモードへの遷移を禁止する
proc = Proc.new {
if $TEST
$DEBUG = false
$TEST = false
$BTEST = false
raise(SecurityHazard ,"Insecure - debug flag can't be change.", caller(1))
end
}
trace_var( :$TEST , proc ) # RPGVX デバッグフラグ
proc = nil
# 戦闘テストで無い場合、戦闘テストへの遷移を禁止する
proc = Proc.new {
if $BTEST
$DEBUG = false
$TEST = false
$BTEST = false
raise(SecurityHazard ,"Insecure - battle test flag can't be change.",
caller(1))
end
}
trace_var( :$BTEST , proc )
proc = nil
end
unless defined? ScriptSyntaxError
# RGSSでは、本来持っているSyntaxErrorの詳細情報をすべて削除してしまい、
# デバッグが非常に困難になってしまいます。
# そのために用意されている例外です。
# ※特にイベントスクリプト上でSyntaxErrorを出すととても悲惨なことに…
# 「スクリプト実行中に SyntaxError が発生しました。」だけで
# すぐに修正できるのでしょうか?
class ScriptSyntaxError < Exception
end
# -------------------------------------------------------------------------
# ◆ 組み込み例外クラス SyntaxError <obsolete>
# -------------------------------------------------------------------------
# RGSSでは、本来持っているSyntaxErrorの詳細情報をすべて削除してしまうため、
# SyntaxError のコンストラクタを乗っ取って別の例外にすりかえています。
# ※ SyntaxError のインスタンスは作成できません。
class << SyntaxError
undef allocate
undef new
#--------------------------------------------------------------------------
# ◆ (!※継承禁止※!)
#--------------------------------------------------------------------------
def SyntaxError.inherited( subclass )
raise( InheritanceError ,
"can't inherit class #{subclass} from #{self}" , caller(1) )
end
private_class_method(:inherited)
# 強制的に別の例外にすりかえる
def new( errors , *args )
error_message = errors
unless (error_message[/^Section(\d+):(\d+):/]).nil?
# セクションを拾い出した場合
nums = $1.to_i
extra = $RGSS_SCRIPTS.at(nums).at(1)
unless $2.nil?
lines = $2.to_i
unless ($RGSS_SCRIPTS.at(nums).at(3)).nil?
splitstr = ($RGSS_SCRIPTS.at(nums).at(3)).split(/\r\n/)
details = ""
if lines < 4
ranges = ( 0...( lines + 3 ))
else
ranges = (( lines - 4 )...( lines + 3 ))
end
for i in ranges
unless (splitstr.at(i)).nil?
if i != (lines - 1)
details += "|" + splitstr.at(i) + "\n"
else
details += ">" + splitstr.at(i) + "\n"
end
else
details += "[End of File]\n"
break
end
end
unless details.empty?
error_message += "\n** script source code:\n" + details
else
error_message += "\n** script source code:#{lines} unknown data.\n"
end
splitstr = nil
end
end
error_message.gsub!(/^Section(\d+):/){"( " + extra + " ):#{$1}:lines "}
end
return ScriptSyntaxError.new(error_message)
end
end
# -------------------------------------------------------------------------
# ◆ RGSS 組み込みモジュール Graphics
# -------------------------------------------------------------------------
class << Graphics
#------------------------------------------------------------------------
# ◆ リセットを無視する Graphics.update
#------------------------------------------------------------------------
def Graphics.safe_update
begin
update
rescue Reset
# リセット操作を無視する。
# ただしカーソルアニメーションなどが巻き戻される。
nil
end
end
end
module Graphics
# -----------------------------------------------------------------------
# ◆ クラス変数
# -----------------------------------------------------------------------
@@rate = 0
@@count = 0
# -----------------------------------------------------------------------
# ◆ フレームレートを一時的に変更
# -----------------------------------------------------------------------
def self.frame_workset( frame_rates )
_critical = Thread.critical
begin
Thread.critical = true
@@rate = Graphics.frame_rate
@@count = Graphics.frame_count
Graphics.frame_rate = frame_rates
ensure
Thread.critical = _critical
end
end
# -----------------------------------------------------------------------
# ◆ フレームレートを元に戻す
# -----------------------------------------------------------------------
def self.frame_restore
_critical = Thread.critical
begin
Thread.critical = true
cnt = Graphics.frame_count - @@count
cnt *= @@rate
cnt /= Graphics.frame_rate
Graphics.frame_count = @@count + cnt
Graphics.frame_rate = @@rate
ensure
Thread.critical = _critical
end
end
# -----------------------------------------------------------------------
# ◆ 解像度横の幅(VXでは無視される)
# -----------------------------------------------------------------------
unless defined? Graphics.width
def self.width
640
end
end
# -----------------------------------------------------------------------
# ◆ 解像度縦の幅(VXでは無視される)
# -----------------------------------------------------------------------
unless defined? Graphics.height
def self.height
480
end
end
end
end
# ---------------------------------------------------------------------------
# ◆ 組み込みモジュール GC
# ---------------------------------------------------------------------------
module GC
module_function
#--------------------------------------------------------------------------
# ◆ 安全にガーベージコレクションを行う
#--------------------------------------------------------------------------
def update_start
Graphics.safe_update
start
Graphics.safe_update
end
end
# -----------------------------------------------------------------------------
# ◆ 組み込みクラス Thread
# -----------------------------------------------------------------------------
class Thread
# ---------------------------------------------------------------------------
# ◆ Thread.critical ブロック
# ---------------------------------------------------------------------------
def self.synchronized
_critical = Thread.critical
begin
Thread.critical = true
yield
ensure
Thread.critical = _critical
end
end
end
}
unless defined? Abstract
# -----------------------------------------------------------------------------
# ◆◆ 組み込みクラス Class
# -----------------------------------------------------------------------------
class Class
# ---------------------------------------------------------------------------
# ◆ クラス変数
# ---------------------------------------------------------------------------
@@_abstract_class = Hash.new
# ---------------------------------------------------------------------------
# ◆ 抽象クラス追加
# ---------------------------------------------------------------------------
def self.abstract_class( klass )
__failure_type_call__( klass ) unless klass.is_a?(Class)
Thread.synchronized do
unless @@_abstract_class[klass.__id__]
@@_abstract_class[klass.__id__] = klass
end
end
end
# ---------------------------------------------------------------------------
# ◆ 抽象クラス判定
# ---------------------------------------------------------------------------
def self.abstract?( klass )
@@_abstract_class[klass.__id__]
end
end
module Abstract
# ---------------------------------------------------------------------------
# ◆ 抽象化
# ---------------------------------------------------------------------------
def self.included( klass )
if klass.include?(FinalClass)
# FinalClass モジュールが既にインクルードされている
raise( IncludeError ,
"can't include #{klass} from #{self}" , caller(1) )
end
Thread.synchronized do
Class.abstract_class( klass )
klass.extend(Abstract_Class__)
end
end
private_class_method(:included)
end
# ---------------------------------------------------------------------------
# ◆ 抽象化 ※ 特異メソッド専用 ※
# ---------------------------------------------------------------------------
module Abstract_Class__
# -------------------------------------------------------------------------
# ◆ ※ 抽象クラス
# -------------------------------------------------------------------------
def allocate
return super unless Class.abstract?( self )
raise( AbstractError ,
"class #{self} cannot use it because of the abstraction class.",
caller(1) )
end
# -------------------------------------------------------------------------
# ◆ ※ 抽象クラス
# -------------------------------------------------------------------------
def new( *args )
return super unless Class.abstract?( self )
raise( AbstractError ,
"class #{self} cannot use it because of the abstraction class.",
caller(1) )
end
# -------------------------------------------------------------------------
# ◆ ※ Mix-in 制限
# -------------------------------------------------------------------------
def self.included( klass )
unless self.is_a?(Class)
raise( IncludeError ,
"can't include #{klass} from #{self}" , caller(1) )
end
end
end
module FinalClass
# ---------------------------------------------------------------------------
# ◆ 継承できないクラス
# ---------------------------------------------------------------------------
def self.included( klass )
if Class.abstract?( klass )
# Abstract モジュールが既にインクルードされている
raise( IncludeError ,
"can't include #{klass} from #{self}" , caller(1) )
end
klass.module_eval(<<-End)
def self.inherited( subclass )
raise( InheritanceError ,
sprintf(\"can't inherit class %s from %s\",subclass.inspect,
self.inspect ) , caller(1) )
end
private_class_method(:inherited)
End
end
private_class_method(:included)
end
# ---------------------------------------------------------------------------
# ◆ 組み込みモジュール Kernel
# ---------------------------------------------------------------------------
module Kernel
# ---------------------------------------------------------------------------
# ◆ 危険な関数を未定義に設定
# ---------------------------------------------------------------------------
# 外部コマンド読み込みなど危険な操作は明示的に禁止にします。
# ※ これらのコマンドの必要性が(通常は)ないうえ、
# 危険(システム破壊をもたらすことがある)なため取り外しています。
# ※ もし、これらを使用する場合は、効果と危険性を考慮してください。
# ---------------------------------------------------------------------------
# 外部コマンドを実行する。
undef `
undef exec # 外部コマンドを実行する 制御を返さない。
undef fork # サブシェルを生成する。
undef system # 外部コマンドを実行する。
undef abort # 後処理を行わずに強制終了する。後処理が必要な時に困る。
undef exit! # abort と同じ。
undef open # コマンドが実行できる。(ファイルを開くならFile.openを用いる)
#--------------------------------------------------------------------------
# 可視性を変更
private
#--------------------------------------------------------------------------
# ◆ RPGVX かどうか
#--------------------------------------------------------------------------
def rpgvx?
if defined? Graphics.resize_screen
return true
else
return false
end
end
#--------------------------------------------------------------------------
# ◆ テストモードかどうか
#--------------------------------------------------------------------------
def debug?
$DEBUG or $TEST
end
#--------------------------------------------------------------------------
# ◆ 例外セット
# 例外を発生させます。
#--------------------------------------------------------------------------
# ◆ method_missing と同様
#--------------------------------------------------------------------------
def __failure_method_call__( method_name , *args )
raise( NoMethodError ,
"undefined method `#{method_name}' for #{self}" , caller(2) )
end
#--------------------------------------------------------------------------
# ◆ オーバーライドが必要
#--------------------------------------------------------------------------
def __override_required_call__( method_name , *args )
raise( AbstractError ,
"It is necessary to do override to use method `#{method_name}'" +
" of this class #{self}. " +
"(or, it tried to call the method of a super-class.)" , caller(2))
end
#--------------------------------------------------------------------------
# ◆ 例外 TypeErrorを発生させる
#--------------------------------------------------------------------------
def __failure_type_call__( object_type )
e = ( object_type.class ).to_s
raise( TypeError , "no implicit conversion from #{e}" , caller(2) )
end
#--------------------------------------------------------------------------
# ◆ 例外 RangeErrorを発生させる ( num が Numeric でない場合はBugDetected )
#--------------------------------------------------------------------------
def __outof_range_call__( num , str , call_value = 2 )
if num.is_a?(Numeric)
if str.is_a?(String)
raise( RangeError , "#{num} out of range of #{str}",caller(call_value))
else
e = ( str.class ).to_s
raise(TypeError,"no implicit conversion from #{e}",caller(call_value))
end
else
e = ( num.class ).to_s
raise( BugDetected, "[BUG] no implicit conversion from #{e} (TypeError)",
caller(1))
end
end
#--------------------------------------------------------------------------
# ◆ 例外 ArgumentErrorを発生させる ( str が String でない場合はBugDetected )
#--------------------------------------------------------------------------
def __invalid_value_call__( str , value , call_value = 2 )
if str.is_a?(String)
raise( ArgumentError , "invalid #{str} for #{value.to_s}")
else
e = ( str.class ).to_s
raise( BugDetected, "[BUG] no implicit conversion from #{e} (TypeError)",
caller(1))
end
end
#--------------------------------------------------------------------------
# ◆ 例外 SecurityErrorを発生させる ( str が String でない場合はBugDetected )
#--------------------------------------------------------------------------
def __insecure_call__( str )
if str.is_a?(String)
raise( SecurityError , "Insecure operation - #{str}" , caller(2) )
else
e = ( str.class ).to_s
raise( BugDetected, "[BUG] no implicit conversion from #{e} (TypeError)",
caller(1))
end
end
#--------------------------------------------------------------------------
# ◆ バグを報告する。 ( str が String でない場合も BugDetected )
#--------------------------------------------------------------------------
def __report_bug( str )
if str.is_a?(String)
raise( BugDetected , str , caller(1))
else
e = ( str.class ).to_s
raise( BugDetected ,
"[BUG] no implicit conversion from #{e} (TypeError)" , caller(1) )
end
end
#--------------------------------------------------------------------------
# ◆ バグを報告する。(異常な値を検出)
#--------------------------------------------------------------------------
def __report_bug_invalid_value( value )
raise( BugDetected , "[BUG] invalid value for #{value}", caller(1))
end
#--------------------------------------------------------------------------
# ◆※!※◆ WF-RGSS の バグを報告する。
# ※ このメソッドは WF-RGSS 内部バグを報告するためのものです。
# ※ カスタマイズ時にバグを報告したい場合は、
# __report_bug( str ) を使用してください。
#--------------------------------------------------------------------------
def __report_internal_bug( str )
if str.is_a?(String)
raise( InternalBugDetected , str , caller(1))
else
e = ( str.class ).to_s
raise( InternalBugDetected ,
"[BUG] no implicit conversion from #{e} (TypeError)" , caller(1) )
end
end
#--------------------------------------------------------------------------
# ◆ チェック関連メソッド
# 型や範囲をチェックします。
#--------------------------------------------------------------------------
# ◆ 型が合わない場合、例外 TypeErrorを発生させる
# (※ klass が異常な場合はBugDetected )
#--------------------------------------------------------------------------
def _type_check_( object_type , klass , call_value = 2 )
begin
return if object_type.is_a?(klass)
e = ( object_type.class ).to_s
raise( TypeError,"no implicit conversion from #{e}")
rescue TypeError => errobj
# 例外の報告位置をすりかえる
if errobj.message[/^no/].nil?
raise( BugDetected , "[BUG] #{errobj.message} (TypeError)",caller(1))
else
raise( TypeError , errobj.message , caller(call_value))
end
end
end
#--------------------------------------------------------------------------
# ◆ Fixnum の範囲を検証する ※範囲が異常なら例外を発生させる
#--------------------------------------------------------------------------
def _fixnum_range_check( value , minimum , maximum )
__failure_type_call__( value , 3 ) unless value.is_a?(Fixnum)
unless value >= minimum and value <= maximum
# 範囲外のため、例外を発生させる
call_ary = caller(1)
if call_ary.size > 0
sections = call_ary.at(0)
str = sections + " ( range #{minimum} .. #{maximum} )"
else
str = "caller method (unknown) ( range #{minimum} .. #{maximum} )"
end
__outof_range_call__( value , str , 3 )
end
end
#--------------------------------------------------------------------------
# ◆ Integer の範囲にまとめる (※処理速度が求められる箇所では用いない)
# ※異常範囲が認められていない場合は、↑のメソッドを用いること
#--------------------------------------------------------------------------
def _integer_range_value( value , minimum , maximum )
__failure_type_call__( value , 3 ) unless value.is_a?(Integer)
if value < minimum
return minimum
elsif value > maximum
return maximum
else
return value
end
end
# ---------------------------------------------------------------------------
# 可視性を変更
public
# これ以降はモジュール関数として定義
module_function
# ---------------------------------------------------------------------------
# ◆ 真 を検証
# ---------------------------------------------------------------------------
def assert_if( value )
unless value
raise(AssertionError,"Assertion Failed (false for true)",caller(1))
end
end
# ---------------------------------------------------------------------------
# ◆ 偽 を検証
# ---------------------------------------------------------------------------
def assert_unless( value )
if value
raise(AssertionError,"Assertion Failed (true for false)",caller(1))
end
end
end
# ---------------------------------------------------------------------------
# ◆ 組み込みクラス Object
# ---------------------------------------------------------------------------
class Object
# 可視性を変更
private
#--------------------------------------------------------------------------
# ◆ Mix-in禁止を実装
#--------------------------------------------------------------------------
def self.__cannot_mixin( klass )
raise( IncludeError ,
"can't include #{klass} from #{self}" , caller(2) )
end
#--------------------------------------------------------------------------
# ◆ 継承禁止を実装
#--------------------------------------------------------------------------
def self.__cannot_inherited( subclass )
raise( InheritanceError ,
"can't inherit class #{subclass} from #{self}" , caller(2) )
end
#--------------------------------------------------------------------------
# ◆ 抽象クラス (かならず継承が必要となる)
#--------------------------------------------------------------------------
def __abstract_class( target )
klass = self.class
unless target.is_a?(Class) or target.is_a?(Module)
__report_bug("[BUG] class or modules required (TypeError)")
end
until ( klass = klass.superclass ) == Object
return if klass == target
end
raise( AbstractError ,
"class #{target} cannot use it because of the abstraction class.",
caller(2) )
end
end
# ---------------------------------------------------------------------------
# ◆ モジュール ErrorLogWriter
# ---------------------------------------------------------------------------
module ErrorLogWriter
#--------------------------------------------------------------------------
# ◆(内部専用)◆ Mix-in 禁止
#--------------------------------------------------------------------------
def self.included( klass )
__cannot_mixin( klass )
end
private_class_method(:included)
# -------------------------------------------------------------------------
# ◆ エラー情報を記録 ( DEBUG のみ )
# -------------------------------------------------------------------------
def self.write( errobj )
return unless debug?
begin
Graphics.safe_update
sleep(0.1)
file = File.open("errors.txt","a")
file.write("*Error - " +
(Time.now).strftime("%Y-%m-%d %H:%M:%S (%A)") + "\n")
file.write( "Exception : #{errobj.class}\n" )
file.write( errobj.message )
unless $@.nil? and $@.empty?
file.write( "\ntrace:\n" + $@.inspect + "\n" )
end
rescue Exception => errs
raise( errs ,
errs.message + "\n (" + (errobj.class).to_s + " )\n" + errobj.message )
ensure
unless file.nil?
file.close
file = nil
end
end
end
end
module Safe_Reseter
# ---------------------------------------------------------------------------
# ◆ クラス変数
# ---------------------------------------------------------------------------
@@__disposer_methods = Hash.new
# ---------------------------------------------------------------------------
# ◆ 解放のためのメソッド定義
# ---------------------------------------------------------------------------
def self._wfsafe_dispose_set( klass , mthd )
@@__disposer_methods[ klass ] = mthd
end
# ---------------------------------------------------------------------------
# ◆ 強制解放
# ---------------------------------------------------------------------------
def _all_disposer
@@__disposer_methods.each do | klass , mthd |
klass.__send__( mthd )
end
begin
Graphics.safe_update
ObjectSpace.each_object( Plane ) do | plane |
plane.dispose unless plane.disposed?
end
ObjectSpace.each_object( Tilemap ) do | tilemap |
tilemap.dispose unless tilemap.disposed?
end
ObjectSpace.each_object( Window ) do | window |
window.dispose unless window.disposed?
end
ObjectSpace.each_object( Bitmap ) do | bitmap |
bitmap.dispose unless bitmap.disposed?
end
ObjectSpace.each_object( Viewport ) do | viewport |
viewport.dispose
end
ObjectSpace.each_object( Sprite ) do | sprite |
sprite.dispose unless sprite.disposed?
end
if rpgvx?
Cache.clear
else
RPG::Cache.clear
end
rescue Hangup
nil
ensure
Graphics.safe_update
end
end
end
#----------------------------------------------------------------------------
# ● Safe_ReseterScene
#----------------------------------------------------------------------------
module Safe_ReseterScene
#--------------------------------------------------------------------------
# ● シーンに適用
#--------------------------------------------------------------------------
def self.setup( klass )
return unless klass.method_defined?(:main)
return if klass.include?(Safe_Reseter)
klass.module_eval(<<-EOM)
include Safe_Reseter
alias _wfrgss_main__ main
def main( *args )
begin
_wfrgss_main__( *args )
rescue Exception
# 例外または F12のリセットで強制解放する
_all_disposer
raise
ensure
_all_disposer if $scene.nil?
end
end
private(:_wfrgss_main__)
EOM
end
end
#----------------------------------------------------------------------------
# ● シーンに適用させる
#----------------------------------------------------------------------------
if WFRGSS::AUTO_DISPOSER
$scene = nil
trace_var( :$scene , Proc.new{ Safe_ReseterScene.setup( $scene.class ) } )
end
end
CODE
#===========================================================================
# ★★ WF-RGSS Scripts ★★
# AutoSave オートセーブスクリプト
# バージョン : rev-3.2 (2008-2-26)
# 作者 : A Crying Minister (WHITE-FLUTE)
# サポート先URI: http://www.whiteflute.org/wfrgss/
# ---------------------------------------------------------------------------
# 機能:
# ・戦闘終了後または移動終了後にセーブを行います。
# CompSave または Comp-SaveDataEXにも対応しています。
# ---------------------------------------------------------------------------
# 設置場所 :Scene_Save(XP)/Scene_File(VX)、
# Comp-SaveData または Comp-SaveDataEXより下、
# Mainより上
# 必要スクリプト:
# ・共通スクリプト、共通実行スクリプト
# 対応スクリプト
# ・Comp-SaveData セーブデータ圧縮スクリプト
# ・Comp-SaveDataEX セーブデータ圧縮暗号化スクリプト
# 注意事項:
# ▽ロードするインターフェースは用意していません。
# セーブデータの個数と相談して設定してください。
#==============================================================================
module WFRGSS_AutoSave
#--------------------------------------------------------------------------
# ● カスタマイズ ポイント
#--------------------------------------------------------------------------
# オートセーブする最初の番号を指定します。
AUTOSAVE_FIRSTNUM = 4
#オートセーブする最後の番号を指定します。
AUTOSAVE_LASTNUM = 4
# 戦闘終了時にセーブをする場合
AFTER_BATTLE = true
# 場所移動後にセーブをする場合
AFTER_MOVE = true
# デバッグ時にセーブ失敗したらエラーにするかを設定します。
FAILED_ERROR = false
# ファイル名を指定します。(sprintf形式)
FILE_NAME = "Save%d"
# バックアップファイルを指定します。
BACKUP_FILENAME = "_backup"
# 実際に使用するセーブファイルの数
SAVEFILE_SIZE = 4
# 以下、設定により自動的に付加されます。
FILENAME_XP = FILE_NAME + ".rxdata"
FILENAME_VX = FILE_NAME + ".rvdata"
BACKUP_FILENAME_XP = BACKUP_FILENAME + ".rxdata"
BACKUP_FILENAME_VX = BACKUP_FILENAME + ".rvdata"
end
unless rpgvx? #RPGXP
class Scene_Load < Scene_File
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
$game_temp = Game_Temp.new # テンポラリオブジェクトを再作成
index = 0
found = false
latest_time = Time.at(0)
for i in 0..WFRGSS_AutoSave::SAVEFILE_SIZE
filename = make_filename(i)
if FileTest.exist?(filename)
file = File.open(filename, "r")
if file.mtime > latest_time and
i < (WFRGSS_AutoSave::AUTOSAVE_FIRSTNUM - 1)
found = true
latest_time = file.mtime
$game_temp.last_file_index = i
end
file.close
end
end
unless found
index = 0
found = false
latest_time = Time.at(0)
for i in 0..WFRGSS_AutoSave::SAVEFILE_SIZE
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
end
end
super("どのファイルをロードしますか?")
end
end
#==========================================================================
==
# ◆ AutoSaveWork (Scene_Save)
#----------------------------------------------------------------------------
# オートセーブを行うクラスです。
#==========================================================================
==
class AutoSaveWork < Scene_Save
# これはシーンオブジェクトではない
undef main if method_defined?(:main)
undef on_decision if method_defined?(:on_decision)
undef update if method_defined?(:update)
#--------------------------------------------------------------------------
# ◆ オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
@autosave_num = WFRGSS_AutoSave::AUTOSAVE_FIRSTNUM
@file_index = 0
end
#--------------------------------------------------------------------------
# ◆ オートセーブ
#--------------------------------------------------------------------------
if defined? WFRGSS_CompSaveEX or defined? WFRGSS_CompSave
def autosave
filename = sprintf(WFRGSS_AutoSave::FILENAME_XP,@autosave_num)
@file_index = @autosave_num - 1
begin
write_savedata(filename)
rescue
raise if debug? and WFRGSS_AutoSave::FAILED_ERROR
else
# 書き込み成功
@autosave_num += 1
if @autosave_num > WFRGSS_AutoSave::AUTOSAVE_LASTNUM
@autosave_num = WFRGSS_AutoSave::AUTOSAVE_FIRSTNUM
end
end
end
else
def autosave
file = nil
filename = sprintf(WFRGSS_AutoSave::FILENAME_XP,@autosave_num)
@file_index = @autosave_num - 1
begin
if FileTest.file?(filename)
File.rename(filename,WFRGSS_AutoSave::BACKUP_FILENAME_XP)
end
rescue SystemCallError => errs
raise "save failed. \n#{errs}"
end
begin
file = File.open(finename,"wb")
write_savedata(file)
file.close
file = nil
rescue Exception => errobj
begin
if FileTest.file?(WFRGSS_AutoSave::BACKUP_FILENAME_XP)
File.rename(WFRGSS_AutoSave::BACKUP_FILENAME_XP,filename)
else
raise "save failed.(backup file not found.) \n#{errobj}"
end
rescue SystemCallError => errs
raise "save failed. \n#{errobj} \n#{errs}"
end
raise if debug? and WFRGSS_AutoSave::FAILED_ERROR
else
# 書き込み成功
@autosave_num += 1
if @autosave_num > WFRGSS_AutoSave::AUTOSAVE_LASTNUM
@autosave_num = WFRGSS_AutoSave::AUTOSAVE_FIRSTNUM
end
ensure
unless file.nil?
file.close unless file.closed?
file = nil
end
end
begin
if FileTest.file?(WFRGSS_AutoSave::BACKUP_FILENAME_XP)
File.delete(WFRGSS_AutoSave::BACKUP_FILENAME_XP)
end
rescue SystemCallError
# バックアップ削除失敗は無視。ただし別の例外は投げる。
end
end
end
end
else # RPGVX
#==============================================================================
# ■ Scene_File
#------------------------------------------------------------------------------
# ファイル画面の処理を行うクラスです。
#==============================================================================
class Scene_File < Scene_Base
#--------------------------------------------------------------------------
# ● タイムスタンプが最新のファイルを選択
#--------------------------------------------------------------------------
def latest_file_index
index = 0
found = false
latest_time = Time.at(0)
for i in 0...WFRGSS_AutoSave::SAVEFILE_SIZE
if @savefile_windows.at(i).time_stamp > latest_time and
i < (WFRGSS_AutoSave::AUTOSAVE_FIRSTNUM - 1)
found = true
latest_time = @savefile_windows[i].time_stamp
index = i
end
end
return index if found
index = 0
latest_time = Time.at(0)
for i in 0...WFRGSS_AutoSave::SAVEFILE_SIZE
if @savefile_windows.at(i).time_stamp > latest_time
latest_time = @savefile_windows[i].time_stamp
index = i
end
end
return index
end
end
#==========================================================================
==
# ◆ AutoSaveWork (Scene_File)
#----------------------------------------------------------------------------
# オートセーブを行うクラスです。
#==========================================================================
==
class AutoSaveWork < Scene_File
# これはシーンオブジェクトではない
undef main if method_defined?(:main)
undef update if method_defined?(:update)
#--------------------------------------------------------------------------
# ◆ オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
@autosave_num = WFRGSS_AutoSave::AUTOSAVE_FIRSTNUM
@index = 0
end
#--------------------------------------------------------------------------
# ◆ オートセーブ
#--------------------------------------------------------------------------
if defined? WFRGSS_CompSaveEXVX or defined? WFRGSS_CompSaveVX
def autosave
@index = @autosave_num - 1
begin
do_save
rescue
raise if debug? and WFRGSS_AutoSave::FAILED_ERROR
else
# 書き込み成功
@autosave_num += 1
if @autosave_num > WFRGSS_AutoSave::AUTOSAVE_LASTNUM
@autosave_num = WFRGSS_AutoSave::AUTOSAVE_FIRSTNUM
end
end
end
else
def autosave
@index = @autosave_num - 1
filename = make_filename(@index)
begin
if FileTest.file?(filename)
File.rename(filename,WFRGSS_AutoSave::BACKUP_FILENAME_VX)
end
rescue SystemCallError => errs
raise "save failed. \n#{errs}"
end
begin
do_save
rescue Exception => errobj
begin
if FileTest.file?(WFRGSS_AutoSave::BACKUP_FILENAME_VX)
File.rename(WFRGSS_AutoSave::BACKUP_FILENAME_VX,filename)
else
raise "save failed.(backup file not found.) \n#{errobj}"
end
rescue SystemCallError => errs
raise "save failed. \n#{errobj} \n#{errs}"
end
raise if debug? and WFRGSS_AutoSave::FAILED_ERROR
else
# 書き込み成功
@autosave_num += 1
if @autosave_num > WFRGSS_AutoSave::AUTOSAVE_LASTNUM
@autosave_num = WFRGSS_AutoSave::AUTOSAVE_FIRSTNUM
end
end
begin
if FileTest.file?(WFRGSS_AutoSave::BACKUP_FILENAME_VX)
File.delete(WFRGSS_AutoSave::BACKUP_FILENAME_VX)
end
rescue SystemCallError
# バックアップ削除失敗は無視。ただし別の例外は投げる。
end
end
end
def do_save
file = File.open( make_filename(@index), "wb")
write_save_data(file)
file.close
end
def return_scene # 無効化
end
end
end
#==============================================================================
# ◆ AutoSave (Scene_Save/Scene_File)
#------------------------------------------------------------------------------
# オートセーブを行うモジュールです。
#==============================================================================
module AutoSave
AUTOSAVE = AutoSaveWork.new
@@enabled = true
#--------------------------------------------------------------------------
# ◆ オートセーブ 可否
#--------------------------------------------------------------------------
def self.enabled?
@@enabled
end
#--------------------------------------------------------------------------
# ◆ オートセーブ 可否設定
#--------------------------------------------------------------------------
def self.enalbed=(value)
@@enabled = value ? true : false
@@enabled
end
#--------------------------------------------------------------------------
# ◆ オートセーブ
#--------------------------------------------------------------------------
def self.autosave
AUTOSAVE.autosave if @@enabled
Graphics.frame_reset
nil
end
end
#--------------------------------------------------------------------------
# ◆ オートセーブ 戦闘終了後
#--------------------------------------------------------------------------
if WFRGSS_AutoSave::AFTER_BATTLE
class Game_Temp
def in_battle=(value)
@in_battle = value ? true : false
AutoSave.autosave unless @in_battle
end
end
end
#--------------------------------------------------------------------------
# ◆ オートセーブ 移動後
#--------------------------------------------------------------------------
if WFRGSS_AutoSave::AFTER_MOVE
unless rpgvx?
class Scene_Map
alias __wfrgss_transfer_player transfer_player
def transfer_player
__wfrgss_transfer_player
AutoSave.autosave
end
end
else
class Scene_Map < Scene_Base
#------------------------------------------------------------------------
# ● 場所移動の処理
#------------------------------------------------------------------------
def update_transfer_player
return unless $game_player.transfer?
fade = (Graphics.brightness > 0)
fadeout(30) if fade
@spriteset.dispose # スプライトセットを解放
$game_player.perform_transfer # 場所移動の実行
$game_map.autoplay # BGM と BGS の自動切り替え
$game_map.update
Graphics.wait(15)
@spriteset = Spriteset_Map.new # スプライトセットを再作成
fadein(30) if fade
Input.update
AutoSave.autosave
end
end
end
end
CODE
#===========================================================================
# ★ WF-RGSS Scripts ★
# 共通実行スクリプト(XP/VX両対応版)
# バージョン : rev-8 (2007-12-17)
# 作者 : A Crying Minister (WHITE-FLUTE)
# サポート先URI: http://www.whiteflute.org/wfrgss/
# ---------------------------------------------------------------------------
# 機能:
# ・デバッグモードで例外が発生したとき、エラーを errors.txt に記録します。
# ・高速なリセットを利用できるようになります。
# ---------------------------------------------------------------------------
# 影響:
# ・ファイルが見つからない例外は、 元の Errno::ENOENT が補足されます。
# ---------------------------------------------------------------------------
# 設置場所 :Mainセクション(一番最後)に上書き
# 必要スクリプト:
# ・共通スクリプト
# 注意事項:
# ▽ 共通スクリプトが必要です。
# 改造して使用することを推奨しますが、そのまま使ってもOKです。
# ▽ デバッグモードでエラーを記録する場合、
# 現在のユーザで書き込みを行えることが必要になります。
#==============================================================================
# ◆ Main ( Execute )
#------------------------------------------------------------------------------
# 各クラスの定義が終わった後、ここから実際の処理が始まります。
#==============================================================================
# ---------------------------------------------------------------------------
# ◆ 処理実行
# ---------------------------------------------------------------------------
$scene = nil # 確実に初期化が行われることを保障するため
# スレッド例外で即座に中断しないようにする。(デバッグ時は無効)
# ※ true に設定する場合はご注意ください。
# 終了する前に解放が必要なものもあります。
Thread.abort_on_exception = false
# RPGVX 互換
if rpgvx?
unless Font.exist?("UmePlus Gothic")
print "UmePlus Gothic フォントが見つかりません。"
exit
end
end
begin
# シーンがない場合は、初期化を行う
if $scene.nil?
# トランジション準備
Graphics.freeze
# シーンオブジェクトを作成
# ★ 最初のシーンはここに設定します。 ★
$scene = Scene_Title.new
# ★ --------------------------------------------------------------------
end
# $scene が有効な限り main メソッドを呼び出す
until $scene.nil?
$scene.main
end
# フェードアウト
Graphics.transition(20)
# 以下、例外処理
rescue BugDetected, InternalBugDetected => errobj
# バグを記録する
ErrorLogWriter.write( errobj )
raise
rescue SyntaxError => errobj
# -------------------------------------------------------------------------
# ◆ 例外 SyntaxError
# -------------------------------------------------------------------------
# この例外はバグかセットアップが適切にされていない状況で無い限り、
# 補足されることはない
ErrorLogWriter.write( errobj )
raise( BugDetected,
"[FATAL] The invalidated exception was detected. \n\n" +
"Exception:\n#{errobj}")
rescue Reset
# -------------------------------------------------------------------------
# ◆ F12 リセット( 例外 Reset < Exception )
# -------------------------------------------------------------------------
# ※retry する場合は、
# かならず、ウィンドウやスプライトが確実に解放される必要があります。
if WFRGSS::AUTO_DISPOSER
$scene = Scene_Title.new
retry
else
raise
end
rescue Hangup => errobj
# -------------------------------------------------------------------------
# ◆ 致命的例外 Hangup
# -------------------------------------------------------------------------
# エラーを記録する
ErrorLogWriter.write( errobj )
# 「スクリプトがハングアップしました。」だけの表示を防止する。
raise( RuntimeError ,
"The processing of the script cannot be continued. (Hangup)" )
rescue SystemExit => errobj
# -------------------------------------------------------------------------
# ◆ 終了要求 ( Alt + F4 など )
# -------------------------------------------------------------------------
# 例外が正常終了で無い場合は、例外 SystemExitを再発生させます。
raise unless (errobj.status).zero?
rescue Exception => errobj
# -------------------------------------------------------------------------
# ◆ 例外処理
# 特に指定されていない例外を補足します。
# ※ rev-2 より、Errno::ENOENT もここで補足します。
# -------------------------------------------------------------------------
# エラーを記録する
ErrorLogWriter.write( errobj )
# 異常終了を通知します。
raise
ensure
# -------------------------------------------------------------------------
# ● 後処理
# -------------------------------------------------------------------------
# 後処理を記述します。
# スクリプト内容によってはここで解放処理が必要になることがあります。
# ★ 後処理を記述します。 ★
# ★ ----------------------------------------------------------------------
end
Customization
1.
CODE
AUTOSAVE_FIRSTNUM
The appointed slot for first auto save file.For example:
CODE
AUTOSAVE_FIRSTNUM = 1
The auto save file will be created on slot 1 and the next auto save file will be created on slot 2.
2.
CODE
AUTOSAVE_LASTNUM
The appointed slot for last auto save file.For example:
CODE
AUTOSAVE_LASTNUM = 2
The auto save file will be created up to slot 2 and the next auto save file will be saved at slot 1 again.
3.
CODE
AFTER_BATTLE = true/false
Set to true to enable auto save after each time the battle end,and false to disable it.
4.
CODE
AFTER_MOVE = true/false
Set to true to enable auto save after each time moving to another map,and false to disable it.
5.
CODE
FAILED_ERROR = true/false
Set to true to enable auto save when save failed while debugging,and false to disable it.
Compatibility
Unknown,there might be some error since the Main script will rewrite the original Main script.
On the other hand,this script also work for XP,but I wont post in XP section,since there is already AutoSave script for XP.
Screenshot
The family doesnt need it.
DEMO
Dowload Demo HereInstallation
This script is plug n play.Just paste the script begin from Base,AutoSave,and Main script in material section,you doesnt need to replace the new main script with the original ones.
FAQ
None yet.
Terms and Conditions
From The Author Site:
1.Credit is needed.(you can credit me too if you want too,lol j/k)
2.There is no obligation to report the error,but feel free to report to us(If you can write nihongo,that is)
3.Can be used for commercial or non-commercial freely,with credit of course.
Note:The White-Flute site also contain an input script,which should
enable the usage of mouse in RMVX,however,I still cant make it to work,so if anybody think they can make the script work,give it a try,Im sure it will be very usefull to many people,since there is no such script that working for VX right now.The link to the WHITE-FLUTE site can be found above.
P/S:for anybody that have been long in the RMXP scene will know what do I mean by the family,dont cha'?

cheers,puppeto4.