【解決】パッチプラグイン

アバター
WTR
記事: 558
登録日時: 2015年12月22日(火) 19:14

【解決】パッチプラグイン

投稿記事by WTR » 2021年6月15日(火) 23:48

ずっと疑問だったことを思い出したので質問させてください。

以下はとあるプラグイン(ひきも記さんの)の一部なのですが

コード: 全て選択

  var _Window_ShopBuy_isEnabled = Window_ShopBuy.prototype.isEnabled;
  Window_ShopBuy.prototype.isEnabled = function(item) {
    var result = _Window_ShopBuy_isEnabled.call(this, item);
    if (result && $gameTemp.isGreedShop()) {
      var materials = DataManager.getGreedShopMaterials(item);
      for (var i = 0; i < materials.length; i++) {
        var material = materials[i];
        var matItem = DataManager.materialToItem(material);
        if ($gameParty.numItems(matItem) < material.need) {
          return false;
        }
      }
    }
    return result;
  };

いろいろ書いてありますが
$gameParty.numItems() を装備品を含めた所持数を返すメソッドを新たに作って差し替えたい、といった場合
もとのプラグインを書き換えずにパッチ対応ってできるでしょうか。

このプラグインの下に置く…となると
もとの isEnabled() を呼んだ時点でその結果はもう望ましくないので使えない
上書きしちゃうのも嫌だし、そもそもどう上書きすればいいのかわからない…
かといって numItems() を書き換えたらエライことになるだろうし…

結局わからなくて、元のプラグインを書き換えちゃったわけですが
本当は嫌だなぁと思っていまして、いい方法があれば教えて頂けますでしょうか。
最後に編集したユーザー WTR on 2021年6月16日(水) 15:08 [ 編集 1 回目 ]

Twitter、はじめました。
https://twitter.com/wtr_in_reverie/
chro
記事: 86
登録日時: 2021年2月14日(日) 11:26

Re: パッチプラグイン

投稿記事by chro » 2021年6月16日(水) 00:58

パッチ作るとしたら、こういうパターンだと特定の条件下で特定の動作になるようにする形ですね。

コード: 全て選択

(function () {
    'use strict';

    var _Window_ShopBuy_isEnabled = Window_ShopBuy.prototype.isEnabled;
    Window_ShopBuy.prototype.isEnabled = function (item) {
        if ($gameTemp.isGreedShop()) $gameParty._equipItemCount = true;
        let result = _Window_ShopBuy_isEnabled.call(this, item);
        if ($gameTemp.isGreedShop()) $gameParty._equipItemCount = false;
        return result;
    };

    var _Game_Party_initialize = Game_Party.prototype.initialize;
    Game_Party.prototype.initialize = function () {
        _Game_Party_initialize.call(this);
        this._equipItemCount = false;
    };

    var _Game_Party_numItems = Game_Party.prototype.numItems;
    Game_Party.prototype.numItems = function(item) {
        let result = _Game_Party_numItems.call(this, item);
        if (this._equipItemCount) {
            result += this.members().reduce((num, actor) => {
                actor.equips().forEach(equip => {
                    if (equip === item) num++;
                });
                return num;
            }, 0);
        }
        return result;
    };

})();
アバター
WTR
記事: 558
登録日時: 2015年12月22日(火) 19:14

【解決】パッチプラグイン

投稿記事by WTR » 2021年6月16日(水) 15:07

ありがとうございます!

やっぱり作れるんですね。
numItems() を弄っちゃいかん…と思い込んでいた節がありましたが
ほかに影響ないように弄ればいいだけなんですね。
画一的な手法があっていつもこうすればOKっていうわけではなさそうなので
慣れるまで悩まされそうですが…

結果的に”装備品を含めた所持数を返す”の部分まで作らせてしまって…
お手数おかけしました。
余談になりますが装備品をカウントするのであっても
いろいろあるなぁ…と眺めていました。reduce() はなかなか慣れなくてパッと出てこない…

ちなみにこんなかんじでカウントしてました。
flatMap() が使えなかったんで余計に回りくどい書き方に…
あとコレ、よく考えたらMVのプラグインでした

コード: 全て選択

  Game_Party.prototype.numItemsWithEquips = function(item) {
    const numItems = this.numItems(item);
    const equips = [].concat(...$gameParty.members().map(member => member.equips()));
    const numEquips = equips.filter(equip => equip && equip === item).length;
    return numItems + numEquips;
  };
Twitter、はじめました。
https://twitter.com/wtr_in_reverie/
chro
記事: 86
登録日時: 2021年2月14日(日) 11:26

Re: 【解決】パッチプラグイン

投稿記事by chro » 2021年6月19日(土) 21:11

このパターンはよく使いますので、そのうち慣れてきます。
最終的には、元のプラグインの実装次第になってしまいますので難しいとこです。

concat/map/filter等は常に新しい配列を作成するので、無駄にならないよう効率化(配列を作成しない/1つ作成したら後はpushで追加)したり、
テストやメンテナンス、使い回しが楽になるのを目的としていたりすると書き方が違ってきます。

reduceは、map/filter/some/forEach等のメソッドで対応しにくい場合や複雑なデータ構造の場合に使うと覚えています。
それで何度も使って慣れていきました。

forEachでも代用できます。

コード: 全て選択

var item = $dataWeapons[1];
var num = 0;
$gameParty.members().forEach(actor => {
    actor.equips().forEach(equip => {
        if (equip === item) num++;
    });
 });



一旦配列を作成する場合でも、pushで追加した方がわかりやすかったります。

コード: 全て選択

var item = $dataWeapons[1];
var equips = [];
$gameParty.members().forEach(actor => actor.equips().forEach(equip => equip === item && equips.push(item)));
var num = equips.length;

“MZ:質問” へ戻る