
SRPG Studio オートセーブ機能で一手ずつ行動を戻す機能を再現しようとしたプラグイン
(2025/01/13)
索敵プラグインとの競合解決しやすいようにプラグインを変更
こんにちは熱帯魚ことRYBAです。
本プラグインを導入すると
オートセーブ機能が追加されます。
事前準備(必須)
Ryba.UndoLoadControlのうちの以下の関数を設定する必要があります
//実際に使っている通常のセーブデータの数を入力します
startUndoSaveCount:function(){
return 50;
},
//オートセーブデータを何個まで記録するかの数
//※startUndoSaveCountと合わせて99を超えるとバグります
maxUndoCount:function(){
return 40;
},
その他の設定項目
ロードしたセーブデータの数を記録する場合、
その変数のテーブルとIDを指定します。
そして、Ryba.UndoLoadCountRecord を trueにします。
また、1マップ中にロードできる回数を制限する場合、
その変数のテーブルとIDを指定します。
Ryba.RewindSystem = true;にします。

//ロードしたセーブデータの数を記録する変数のテーブル番号を記載します。
//※タブの番号は「0」、「1」、「2」....となっている点に注意
Ryba.SaveCountTableId = 0;
//ロードしたセーブデータの数を記録する変数のIDを記載します。
Ryba.SaveCountVariableId = 1;
//ロードしたセーブデータの数を記録するかどうか
Ryba.UndoLoadCountRecord = false;
//巻き戻し機能化するかどうか
//trueにするとロードできる回数などが指定できます
//(ツール側にデフォルトであるマップセーブがオフにしないとプレイヤーが簡単に不正出来てしまう欠点があります)
//trueにするとタイトルからは選べなくなります(マップ攻略中のみ選択可能に)
Ryba.RewindSystem = true;
//巻き戻せる回数
Ryba.RewindMaxCount = 10;
//巻き戻し回数を保存する変数を設定
//これは「ロードしたセーブデータの数を記録する」変数とは別の物にする必要があります
//※タブの番号は「0」、「1」、「2」....となっている点に注意
Ryba.RewindCountTableId = 0;
//変数のIDを記載します。
Ryba.RewindCountVariableId = 2;
環境
オートセーブに関する項目が二つ増えます。

「オートセーブ最新読込」は
オフにすると単純に一番最後にセーブしたデータが最新となりますが、
オンにするとロードしたデータが最新データとなり、
一手戻しっぽくなります。
カスタマイズ(重いとき)
ぶっちゃけターンの開始時だけで良い場合は
810行目のgetFlagValue関数部分を変更しましましょう。
getFlagValue: function() {
if (typeof root.getExternalData().env.autoSaveType !== 'number') {
return AutoSaveType.Turn;
}
return root.getExternalData().env.autoSaveType;
}
初期設定が「ターン」になります。
「ユニット」を項目から消したい場合
getFlagCount: function() {
return 2;
},
getObjectArray: function() {
return [ 'なし', 'ターン' ];
}
としましょう。
索敵プラグイン(競合解決方法)
(作業で行数が変化する恐れがあるので上から順番にやってみてください)
対象プラグイン
「索敵・(FMPL氏作、名前未定(仮)氏改変対応版)」
https://ci-en.net/creator/4919/article/808431
索敵プラグイン側の変更
索敵マップPLターン処理.js
1.PlayerTurn._moveUnitCommand関数内の
this._changeEventMode();を
this._changeEventModeNeo(true);
に書き換える
(行数でいうと147行目)
2.次に135行目のPlayerTurn._moveUnitCommand
return alias5.call(this);
この一行を消し、その部分に、
「UndoLoadControl.js」
PlayerTurn._moveUnitCommand関数の960行目~972行目辺りの処理を
コピペします。
その後、959行目~973行目辺りの処理を削除します
(元の場所の処理を削除して要するにそのまま移植)
PlayerTurn._moveUnitCommand = function() {
var result = this._mapSequenceCommand.moveSequence();
if (result === MapSequenceCommandResult.COMPLETE) {
this._mapSequenceCommand.resetCommandManager();
MapLayer.getMarkingPanel().updateMarkingPanelFromUnit(this._targetUnit);
this._changeEventModeNeo(true);
}
else if (result === MapSequenceCommandResult.CANCEL) {
this._mapSequenceCommand.resetCommandManager();
this.changeCycleMode(PlayerTurnMode.MAP);
}
return MoveResult.CONTINUE;
};
(コピペするときは一番上の行と一番下の行はいらない。消すときはそれも消す)
変更後の関数内の処理はこうなるはず
var alias5 = PlayerTurn._moveUnitCommand;
PlayerTurn._moveUnitCommand = function () {
var state = CurrentMap.getSearchState();
if (state !== SearchStateType.NOTSEARCH) {
var result = this._mapSequenceCommand.moveSequence();
if (result === MapSequenceCommandResult.COMPLETE) {
CurrentMap.updateData(UnSeenMapType.PLAYERUNIT);
CurrentMap.updateData(UnSeenMapType.ENEMYUNIT);
CurrentMap.updateData(UnSeenMapType.ALLYUNIT);
// MapLayer.getMarkingPanel().updateMarkingPanel();
MapLayer.getMarkingPanel().updateMarkingPanelFromUnit(this._targetUnit);
this._changeEventModeNeo(true);
}
else if (result === MapSequenceCommandResult.CANCEL) {
MapLayer.getMarkingPanel().updateMarkingPanelFromUnit(this._targetUnit); // 追加
this.changeCycleMode(PlayerTurnMode.MAP);
}
return MoveResult.CONTINUE;
}
var result = this._mapSequenceCommand.moveSequence();
if (result === MapSequenceCommandResult.COMPLETE) {
this._mapSequenceCommand.resetCommandManager();
MapLayer.getMarkingPanel().updateMarkingPanelFromUnit(this._targetUnit);
this._changeEventModeNeo(true);
}
else if (result === MapSequenceCommandResult.CANCEL) {
this._mapSequenceCommand.resetCommandManager();
this.changeCycleMode(PlayerTurnMode.MAP);
}
return MoveResult.CONTINUE;
};
索敵マップ基本処理.js
46行目以下の記述をします。
var Ryba = Ryba || {};
次に768行目のCurrentMap.checkIsSearch関数を変更します。
まず、
774行目の
if (type !== SceneType.REST) {
を削除して
代わりに以下の2行を記述します
if (Ryba.UndoLoadControl.SearchCheckFlag || type !== SceneType.REST) {
Ryba.UndoLoadControl.SearchCheckFlag = false;
最後に796行目辺りの
if( UnSeenMapAnyMapDataObject != null ) {
の1つ上に
以下の4行を追加します
if( UnSeenMapAnyMapDataObject == null ) {
UnSeenMapAnyMapDataObject = Ryba.UndoLoadControl.UnSeenMapAnyMapDataObject;
}
Ryba.UndoLoadControl.UnSeenMapAnyMapDataObject = null;
武器強化プラグイン(競合解決方法)
対象プラグイン
「プラグイン:武器強化・(名前未定(仮)氏作)」
※(行数が変化するため必ず上から順番に作業を行ってください)
「UndoLoadControl.js」
武器強化.js、404行目の
obj.PowerUpWeaponDataObject_ = WeaponGrowthControl.createGrowthWeaponDataObject();
この処理を
UndoLoadControl.js270行目あたりの_getCustomObject関数内に追加します。
getCustomObject: function(param,autoSaveData) {
//TODO:a
//ver1.280から構造が変わったため修正
//セーブのカスタムオブジェクトを変更している場合、
//このobj変数もからではなく同じように変更しなければならない
//var obj = LoadSaveScreen._getCustomObject.call(this);
var obj = {};
obj.saveCount = Ryba.CommonControl.getToolVariable(Ryba.SaveCountTableId,Ryba.SaveCountVariableId);
this._setLeaderSettings(obj, autoSaveData.unit);
this._setPositionSettings(obj, param);
obj.titleType = autoSaveData.titleType;
if(CurrentMap.createAnyMapDataObject !== undefined){
obj.UnSeenMapAnyMapDataObject = CurrentMap.createAnyMapDataObject();
}
obj.PowerUpWeaponDataObject_ = WeaponGrowthControl.createGrowthWeaponDataObject();
return obj;
},
こんな感じになるはずです。
次に
武器強化.js、420行目のあたりの
var powerUpWeaponDataObject_ = object.custom.PowerUpWeaponDataObject_;
// ロードファイルに独自データがあれば読み込む
if( typeof powerUpWeaponDataObject_ !== 'undefined' ) {
//root.log('growthWeaponDataObject_データあり');
// バックアップデータのロード
WeaponGrowthControl.updateGrowthWeaponDataObject(powerUpWeaponDataObject_);
// バックアップデータ読み込みのフラグセット
WeaponGrowthControl.setDataLoadFlag(true);
}
else {
root.log('customData データなし');
}
この部分の処理を
UndoLoadControl.js147行目あたりに挿入します
この時、
var powerUpWeaponDataObject_ = object.custom.PowerUpWeaponDataObject_;
この部分は
var powerUpWeaponDataObject_ = data.data.custom.PowerUpWeaponDataObject_;
とします。
executeLoad:function(data){
this._isActivatedFromSaveFile = true;
var unSeenMapAnyMapDataObject = data.data.custom.UnSeenMapAnyMapDataObject;
// ロードファイルに独自データがあれば読み込む
if( typeof unSeenMapAnyMapDataObject !== 'undefined' ) {
this.UnSeenMapAnyMapDataObject = unSeenMapAnyMapDataObject;
}else{
this.UnSeenMapAnyMapDataObject = null;
}
var powerUpWeaponDataObject_ = data.data.custom.PowerUpWeaponDataObject_;
// ロードファイルに独自データがあれば読み込む
if( typeof powerUpWeaponDataObject_ !== 'undefined' ) {
//root.log('growthWeaponDataObject_データあり');
// バックアップデータのロード
WeaponGrowthControl.updateGrowthWeaponDataObject(powerUpWeaponDataObject_);
// バックアップデータ読み込みのフラグセット
WeaponGrowthControl.setDataLoadFlag(true);
}
else {
root.log('customData データなし');
}
if(ConfigItem.AutoSaveIndexUpdate.getFlagValue() === AutoSaveIndexType.Update){
Ryba.UndoLoadControl.setNowSaveIndex(data.autoIndex);
}
var beforeValue;
if(Ryba.RewindSystem){
beforeValue = Ryba.CommonControl.getToolVariable( Ryba.RewindCountTableId,Ryba.RewindCountVariableId);
}
root.getLoadSaveManager().loadFile(data.saveFileIndex);
if(Ryba.RewindSystem){
Ryba.CommonControl.setToolVariable( Ryba.RewindCountTableId,Ryba.RewindCountVariableId, beforeValue + 1);
}
},
こんな感じになるはずです
「武器強化.js」
481行目~931行目の処理を切り取ります。
そして、302行目にペーストします。
(オートセーブで呼び出すためにグローバル化します)
注意点
あくまでオートセーブ機能です。
(巻き戻しを主目的とした機能ではないです)
また、ユニットの行動毎にセーブするため
セーブ容量の多い作品ではかなり重くなり、
事実上実装できない可能性があります。
Plguin
https://github.com/RYBA549/RYBA_SrpgStudio/blob/master/UndoLoadControl.js
PS
参考までにこちらもどうぞ↓
https://note.com/nettaigyo10ryba/n/ndd3158fd56c3
履歴
(2025/01/13)
索敵プラグインとの競合解決しやすいようにプラグインを変更
(2023/12/27)
ターンを選んだ時にエラーになるのを修正しました。
(2023/04/06)
ロードできる回数を設定できるモードを追加しました。
指定回数以上ロードするとそのマップでは
オートセーブデータをロードできなくなります。
(オートセーブ機能なのでなんか変ですが)
使用する場合はマップセーブ廃止推奨です
(オートセーブの都合上プレイヤーが悪さしやすくなります)
公式の中断セーブプラグインなどを代わりに入れましょう。