fc2ブログ

「二刀流」と「両手持ち武器」の両立を考察

少し前に「両手持ち武器」プラグインのMZ移植と機能追加の要望メールをいただいました。

現在のツクールの仕様だと、「盾スロットを封印した武器」を両手持ち武器として制作したとしても、「二刀流」では両手に持ててしまいます。
上記のプラグインはそれに対応したものです。

ただこのプラグインは簡単に対応できる部分のみしか対応していません。
細かい部分にまで対応するとなると改変する部分が多く、競合の発生率が高くなるため、断らせていただきました。
(後述しますが、公式が対応する可能性が高いという理由もあります。)

今回は「もし対応するとしたらどんな改変が必要になるか」について、私の意見を書いてみたいと思います。

なお、今回の記事に書かれている内容は全て頭の中で組み立てただけのコードであり、実際に動作テスト等は行っておりません
間違った箇所が存在する可能性もあるので、それを理解したうえで読んでください。

公式が予定しているパッチを考察

今回の二刀流の件ですが、公式も以下のような修正を行うとパッチノートに書かれています。
  • 特徴にて盾を封印した武器と「二刀流」を設定した武器は、先に二刀流の武器を装備すると盾を封印した武器が装備できる問題を修正
  • 特徴「二刀流」が設定されているとき、イベントコマンドの装備の変更「武器=なし」で2スロット目(盾部位)の武器が残る問題を修正
ただしこの修正はバージョン1.4.4で行う予定と書かれているのですが、現行のバージョン1.5でもまだ対応していません。

まずはこれらについて、私だったらどういった修正を行うのか考えてみたいと思います。

特徴にて盾を封印した武器と「二刀流」を設定した武器は、先に二刀流の武器を装備すると盾を封印した武器が装備できる問題を修正

まず内容を整理すると、
二刀流を設定した武器」を先に装備するとサブ武器に「盾を封印した武器(両手持ち武器)」が装備できてしまう不具合
ということでしょうか。

「なぜ武器に二刀流?」という疑問はありますが、これは私が公開しているプラグインで対処している部分です。
私のプラグインでは「盾が封印されている場合、二刀流のサブ武器スロットも封印する」という処理を行っています。

ただ、結構昔に作ったプラグインなので、内容はあまりよくないです。
今だったら下のようなコードを使ったスクリプトに変更します。
Game_Actor.prototype.isSecondWeaponSlot = function(slotId) {
    return slotId === 1 && this.isDualWield();
};
サブ武器の装備スロットかどうかを判定します。
これがあると後々便利。

実をいうとこれではまだ対応不十分なのですが、それについてはまた後で。
とりあえずこの問題は対応は出来ているとします。

特徴「二刀流」が設定されているとき、イベントコマンドの装備の変更「武器=なし」で2スロット目(盾部位)の武器が残る問題を修正

これはよくわからないです。
私が確認した限り、サブ武器の付け外しもできます。

メイン武器を外した場合、サブ武器だけ残るのが不具合ということなのでしょうか?
だとしたら、そもそも装備画面でサブ武器だけ装備できることも不具合になるような気がします。

もしそうであれば、そのように修正してみましょう。

まずは装備画面で、「二刀流を持っているキャラがメイン武器を装備していない場合、サブ武器を変更不可」にします。
const _Game_Actor_isEquipChangeOk = Game_Actor.prototype.isEquipChangeOk;
Game_Actor.prototype.isEquipChangeOk = function(slotId) {
    return (
        _Game_Actor_isEquipChangeOk.apply(this, arguments) &&
        !(this.isSecondWeaponSlot(slotId) && !this.equips()[0])
    );
};
おそらくこれでサブ武器は変更できなくなります。

あとは、「二刀流を持っているキャラがメイン武器を装備していない場合、サブ武器を強制的に外す」処理です。
const _Game_Actor_releaseUnequippableItems = Game_Actor.prototype.releaseUnequippableItems;
Game_Actor.prototype.releaseUnequippableItems = function(forcing) {
    if (this.isDualWield()) {
        const equips = this.equips();
        if (!equips[0] && equips[1]) {
            if (!forcing) {
                this.tradeItemWithParty(null, equips[1]);
            }
            this._equips[1].setObject(null);
        }
    }
    _Game_Actor_releaseUnequippableItems.apply(this, arguments);
};
汎用性の低いコードですが、とりあえず動けばOKということで。

サブ武器に両手持ち武器を装備できないようにする

「両手持ち武器」プラグインで二刀流と両手持ちは両立できなくなっていますが、対応できていない部分があります。
それは「装備画面でサブ武器変更時に、両手持ち武器が表示される」ことです。

選択したところで装備はできません。
出来ないものが表示されるのはおかしいことなので、一覧に表示されないようにする必要があります。

まずは両手持ち武器かどうかを判定する関数を作ります。
DataManager.isTwoHandWeapon = function(item) {
    if (!this.isWeapon()) {
        return false;
    }
    const code = Game_BattlerBase.TRAIT_SLOT_TYPE;
    return item.traits.some(trait => trait.code === code && trait.dataId === 1);
};
最後いろいろと端折ってますが、動作すれば良しということで。

DataManager クラスに定義しているのは、アイテムの判定に関するメソッドは大抵ここにあるからです。
プラグイン素材であれば、関数式で定義しても良いと思います。
Game_BattlerBase の定数を使っているからといって Game_BattlerBase 系のクラスに定義する必要はないと思います。

引数として送られてくるオブジェクトが必ず武器であるのなら、最初の isWeapon の判定はいらないかもしれませんが、念のため入れておきます。

次に、装備できるアイテム一覧に両手持ち武器を表示させない処理です。
const _Window_EquipItem_includes = Window_EquipItem.prototype.includes;
Window_EquipItem.prototype.includes = function(item) {
    if (!_Window_EquipItem_includes.apply(this, arguments)) {
        return false;
    }
    if (item === null) {
        return true;
    }
    return (
        this._actor &&
        !(this._actor.isSecondWeaponSlot(this._slotId) && DataManager.isTwoHandWeapon(item))
    );
};
たぶんこんな感じ。(動作しなかったらすみません)

サブ武器に両手持ち武器を装備したら外すようにする

ここまでの処理でほぼ完成なのですが、念のため何らかの理由でサブ武器に両手持ち武器が装備された際に外すような処理を作っておきます。

プレイヤーからは既に変更できないので無くても良いと言えば良いのですが、もし何らかのプラグインやイベントコマンドで装備された場合を想定した対処です。

処理は上で書いた Game_Actor.prototype.releaseUnequippableItems に追加します。
const _Game_Actor_releaseUnequippableItems = Game_Actor.prototype.releaseUnequippableItems;
Game_Actor.prototype.releaseUnequippableItems = function(forcing) {
    if (this.isDualWield()) {
        const equips = this.equips();
        if (!equips[0] && equips[1]) {
            if (!forcing) {
                this.tradeItemWithParty(null, equips[1]);
            }
            this._equips[1].setObject(null);
        }

        // ここから
        const weapon2 = this.equips()[1]
        if (DataManager.isTwoHandWeapon(weapon2)) {
            if (!forcing) {
                this.tradeItemWithParty(null, weapon2);
            }
            this._equips[1].setObject(null);
        }
        // ここまで

    }
    _Game_Actor_releaseUnequippableItems.apply(this, arguments);
};

武器の減少でサブ武器から外すようにする

二刀流時にメイン武器を装備していない状態でサブ武器を装備することが不具合だとしたら、さらに修正しないといけない箇所があります。
それは「同じ武器を2つ装備している状態で[武器の増減]で装備品を含んで減らす場合、メイン武器から外されてしまう」という問題です。

単純に装備を上から外しているので、下からにします。
Game_Actor.prototype.discardEquip = function(item) {
    const slotId = this.equips().lastIndexOf(item);
    if (slotId >= 0) {
        this._equips[slotId].setObject(null);
    }
};
indexOflastIndexOf に変えただけです。



ご要望いただいた内容は今回の記事で書いた内容とは違い、かなり複雑な処理を必要とするためお断りしてしまいました。
公式がおそらく対応するし、二刀流と両手持ち武器の問題はこの記事のコード使わずとも、プラグインを探したらあるという理由もあります。

こんな感じにプラグイン作ってますよという作業の流れが伝わったらいいなと思います。

スポンサーサイト



tag : JavaScriptRPGツクールMZ二刀流

2022-06-25 : スクリプト日記 : コメント : 0 : トラックバック : 0 :
コメントの投稿
非公開コメント

« next  ホーム  prev »

プロフィール

木星ペンギン

Author:木星ペンギン
ほぼツクールのことばかり書いてます。
名前は↑から取りました。
木製ですが木星です。
トカゲは関係ありません。

ゲーム

  • 箱庭の勇者たち(体験版)
  • ぼくらの大革命!
  • 走ってぶつかるゲーム
  • ビート☆サムライ

メールフォーム

wood_penguin@yahoo.co.jp

名前:
メール:
件名:
本文:

月別アーカイブ

広告

寄付(Donate)