気ままなタンス*プログラミングなどのノートブック

プログラミングやRPGツクール、DTM等について、学んだことや備忘録をアウトプットとして残し、情報を必要としている誰かにとって「かゆいところに手が届く」ブログとなることを願いながら記事を書いています。

【RPGツクールMV】[中級者向け]ItemCombination.jsでゲーム再起動時にレシピが消える問題対策(アイテム合成システムプラグイン)

スポンサーリンク

先日、以下の記事で、「Jeremy Cannadyさん」が作成されたアイテム合成システムプラグイン ItemCombination.jsの利用方法に関する備忘録を掲載しました。 rinnegrid.hatenablog.com

プラグインの問題点

素晴らしいプラグインなのですが、1点だけ問題(?)があります。

  • ゲームを終了するとレシピが消えてしまう
    • セーブしてもダメ

というのも、自分の環境ではプラグインの利用頻度が少なく気づかなかったのですが、 以下のようなツイートをお見かけし、自分なりに対策しようと思いました。

この合成プラグインは一回ゲーム落としたら作れるリスト吹っ飛んでしまう

対策の検討

もしかしたら、別のサイトに対策済みのコードがあるかもしれませんが、 ひとまず、自分用として対策をしてみました。 本稿の後半に、メリット・デメリットを記載しますが、 同じように対策する場合は注意が必要です。

対策の方針

  • ある範囲のスイッチを利用し、レシピの習得状態を保存する形にします。
  • レシピ状態を示すスイッチは1000番目以降を使う形とします

  • 事前にやること

    • スイッチの最大数変更
      データとして利用可能なアイテム最大数を100とすると、 スイッチとしては1001番目から1101番目までが必要となります。 従って、スイッチの最大数を変更しておく必要があります。

対策コード

1. itemcombination.js(以下プラグイン)の一番下に以下のコードを追記します

Scene_CraftingMenu.prototype.switch_start_index = function() {
    return 1000;
};

2. プラグインの566行目あたりのitemComboForget_pluginCommand関数を置き換えます

// 566行目あたり
var itemComboForget_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
    itemComboForget_pluginCommand.call(this, command, args);
    if (command === "itemComboForget") {
        var arg = $dataItems[JSON.parse(args[0])].name;
        $gameParty.forgetRecipe(arg);

        // 以下の3行を追加
        // アイテムNo+1000番目のスイッチを利用し、レシピ状況を削除する
        var base_index = Scene_CraftingMenu.prototype.switch_start_index();
        var item_no = JSON.parse(args[0]);
        $gameSwitches.setValue(base_index+item_no, false);

    };
};

3. プラグインの547行目あたりのitemComboLearn_pluginCommand関数を置き換えます

// 547行目あたり
var itemComboLearn_pluginCommand = Game_Interpreter.prototype.pluginCommand;
Game_Interpreter.prototype.pluginCommand = function(command, args) {
    itemComboLearn_pluginCommand.call(this, command, args);
    if (command === "itemComboLearn") {
        var arg = $dataItems[JSON.parse(args[0])].name;
        $gameParty.learnRecipe(arg);

        // 以下の3行を追加
        // アイテムNo+1000番目のスイッチを利用し、レシピ状況を保存する
        var base_index = Scene_CraftingMenu.prototype.switch_start_index();
        var item_no = JSON.parse(args[0]);
        $gameSwitches.setValue(base_index+item_no, true);
    };
};

4. プラグインの453行目あたりのScene_CraftingMenu.prototype.create関数を置き換えます

// 453行目あたり
Scene_CraftingMenu.prototype.create = function() {
   Scene_MenuBase.prototype.create.call(this);

    var base_index = this.switch_start_index();
    if($gameParty._craftingLearnedRecipes < 1) {
        Game_Party.prototype.populateCraftingRecipes();

        // $dataItems.length: 定義上のアイテム数が100であれば、+1した101が戻る)
        for(var i = base_index+1; i < base_index+$dataItems.length; i++) {
            // アイテムIDとスイッチのひもづけより、スイッチがONであればレシピを追加
            if($gameSwitches.value(i)){
                var item_no_diff = i - base_index;
                var arg = $dataItems[item_no_diff].name;
                $gameParty.learnRecipe(arg);
            }
        }
    }

   this.createTitleWindow();
   this.createCommandWindow();
   this.createDetailsWindow(); 
   this.createCombineWindow();

};

動作確認

※音が鳴りますのでご注意ください

http://www.rinsymbol.sakura.ne.jp/tkool/mv/develop_itemcomb_custom/

対策のメリット

  • セーブしてゲームを一度終了したとしても、レシピ情報が適切に表示されます

対策のデメリット

  • スイッチを「アイテム数」だけ確保する必要があります
  • スイッチの管理に気を配る必要があります
    • アイテムが増えると、そのアイテム番号に+1000したスイッチ番号が使われる可能性があるためです。
  • 別の方が作成したプラグインへの独自追加なので、動作が保障されません
  • 元のプラグインのバージョンアップ等でソースコードに変更があった場合は対応する必要あります

1000番目以降のスイッチしか利用できないのか?

そんなことはありません。 switch_start_index関数の「1000」と書かれている部分を別の数字に変更すれば、その番号のスイッチを開始位置とします 9999までスイッチを作成できるので、例えば9000を開始位置とするのもありです。 ただ、デバッグ時のスイッチ確認のときに、スクロールがかなり面倒だと思われます。

別のやり方に関する検討

別の方法でやるとすると、どんな案があるかを妄想していたので、 メモを残します。

別のやりかた:ゲームロード時に、スイッチの状態を見て、内部的にプラグインコマンドを発行する

  • レシピを覚えた時点で、「○○のレシピを覚えた」というスイッチをONにする。
  • セーブして終了
  • ロード時点で、該当のスイッチ(決まった範囲)を確認し、もしONであればitemComboLearn xを、JavaScript上で呼び出す