カウンター周りの挙動

しぐれん

ユーザー
BattleManager.invokeAction()周辺って、処理をフックしにくいと思うのですが、他の方の意見を聞きたいです。
PHP:
BattleManager.invokeAction = function(subject, target) {
    this._logWindow.push('pushBaseLine');
    if (Math.random() < this._action.itemCnt(target)) {
        this.invokeCounterAttack(subject, target);
    } else if (Math.random() < this._action.itemMrf(target)) {
        this.invokeMagicReflection(subject, target);
    } else {
        this.invokeNormalAction(subject, target);
    }
    subject.setLastTarget(target);
    this._logWindow.push('popBaseLine');
    this.refreshStatus();
};
事前にトリアコンタンさんのカウンター拡張プラグインを調べたのですが、判定が全てGame_action.itemCnt()でやらざるを得ないのが辛いです。
自分のプロジェクト用にプラグインを作るだけならmanagerを直接書き換えればいいのですが、配布を考えるとそうもいかず。

こんな形になっていたら理想的なんですが、どうでしょうか。
カウンタープラグインはaction.itemCnt()にフックする形が多いので、この変更であれば影響は小さいと予想しています。
他にも、変更したらフックしやすそうな場所があります。

PHP:
BattleManager.counterTest =function(action,target){
    return Math.random() < action.itemCnt(target);
};
BattleManager.invokeAction = function(subject, target) {
    this._logWindow.push('pushBaseLine');
    if ( this.counterTest(action,target) ) {
        this.invokeCounterAttack(subject, target);
    } else if (this.magicReflectionTest(action,target)) {
        this.invokeMagicReflection(subject, target);
    } else {
        this.invokeNormalAction(subject, target);
    }
    subject.setLastTarget(target);
    this._logWindow.push('popBaseLine');
    this.refreshStatus();
};
githubにあるツクールMVのリポジトリにプルリクエストを送るべきなんでしょうが、gitの使い方にまだ慣れていないのでここに書きました。
 

トリアコンタン

モデレーター
スタッフ
モデレーター
こんにちは!
そうですね。一部の判定は別メソッドとして切り出してくれると嬉しい箇所が結構あります。
とはいえ、OSS版の導入率が不透明であること、内部処理のみの変更のプルリクエストが受理される見込みが
あまり高くないことを考慮すると、現状で妥協点を見いだすのが次善かと個人的には考えています。

現状でitemCntをフックする以外のやり方として、以下のようなやり方があります。
もちろん条件次第でinvokeActionの元の処理が呼ばれなくなるリスクはありますのでそこは注意です。

コード:
BattleManager.counterTest =function(action,target){
    return false;//プラグイン専用のカウンター判定
};

var _BattleManager_invokeAction = BattleManager.invokeAction;
BattleManager.invokeAction = function(subject, target) {
    if (this.counterTest(this._action, target)) {
        this._logWindow.push('pushBaseLine');
        this.invokeCounterAttack(subject, target);
        subject.setLastTarget(target);
        this._logWindow.push('popBaseLine');
        this.refreshStatus();
    } else {
        _BattleManager_invokeAction.apply(this, arguments);
    }
};
 
トップ