【解決】メニューでアイテム使用時、回復量のポップアップ表示をしたい

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

【解決】メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by WTR » 2023年1月14日(土) 14:49

Window_MenuActor に Sprite_Actor を追加して、アイテムの回復量を表示しようと試みているのですが
対象が味方全体の回復アイテムを使用したとき、パーティーの先頭キャラクターにだけ
ポップアップが表示されないという現象にぶち当たって解決できずにいます。

実際組み込む予定なのは別のプラグインなのですが
本質と考えられる部分だけ切り出した雑な実験プラグインでも再現したので添付します。
どこに問題がありそうか、ヘルプを頂けないでしょうか。

■再現手順
新規プロジェクトを作成(コアスクリプトは V1.6.0)し、実験プラグインを追加。
データベースのシステム1から戦闘画面をサイドビューに変更(Sprite_Actor が表示されないため)
適当な全体回復アイテムを作成、アイテムメニューで使用する。
添付ファイル
スクリーンショット 2023-01-14 143713.png
DamagePopupOnMenu.js
(1.16 KiB) ダウンロード数: 4 回
最後に編集したユーザー WTR on 2023年1月14日(土) 16:44 [ 編集 1 回目 ]

Twitter、はじめました。
https://twitter.com/wtr_in_reverie/
アバター
まっつUP
記事: 1155
登録日時: 2016年8月11日(木) 15:38
お住まい: タケノコ王国

Re: メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by まっつUP » 2023年1月14日(土) 16:17

WTR様

どうやら、アイテムやスキルの使用者にポップアップが表示されない場合があるようです。
(薬の知識の値に差異がなければおそらく先頭のアクターが使用者)
なぜ使用者だけ表示されないのかはまだ分かりません。
RPGで笑顔を・・・

ツイッター(ツクラーの巣窟)(閲覧は自己責任でお願いします)
https://twitter.com/mattuup

github
https://github.com/mattuup/RPGMakerMZ
名無し蛙
記事: 304
登録日時: 2015年11月23日(月) 02:46

Re: メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by 名無し蛙 » 2023年1月14日(土) 16:18

軽く調べた範囲ですけどおおよそは分かりました。
多分原因はrmmz_objects.jsの1904行目だと思います。

コード: 全て選択

Game_Action.prototype.apply = function(target) {
    const result = target.result();
    this.subject().clearResult(); // これかな
    result.clear();
    result.used = this.testApply(target);
    result.missed = result.used && Math.random() >= this.itemHit(target);
    result.evaded = !result.missed && Math.random() < this.itemEva(target);
    result.physical = this.isPhysical();
    result.drain = this.isDrain();
    if (result.isHit()) {
        if (this.item().damage.type > 0) {
            result.critical = Math.random() < this.itemCri(target);
            const value = this.makeDamageValue(target, result.critical);
            this.executeDamage(target, value);
        }
        for (const effect of this.item().effects) {
            this.applyItemEffect(target, effect);
        }
        this.applyItemUserEffect(target);
    }
    this.updateLastTarget(target);
};

まずポップアップが表示されないアクターですけど厳密には先頭アクターではなくアイテムの使用者です。
特殊能力値「薬の知識」が高いアクターがパーティの中から選出され
全員同値の場合は先頭メンバーが選ばれる、と思います。
つまりthis.subject()の部分です。
全てのアクターに対してアイテム効果を適用する度に自身のリザルトもクリアする為、
効果は反映されるもののポップアップには反映されず、という中途半端な状態になるのではないか、と。
まぁ、つまり仕様というか想定外の使われ方をしたが故、ですかね。
一応、最後尾のメンバーの「薬の知識」を上げれば結果として全員ダメージポップアップが表示されます。
アバター
WTR
記事: 559
登録日時: 2015年12月22日(火) 19:14

Re: 【解決】メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by WTR » 2023年1月14日(土) 16:50

ありがとうございます!
なるほど、使用者に反映されないという現象だったのですね。
ターゲットの配列を逆順にソートしてもポップアップが出ないのはパーティーの先頭キャラクターだったので
パーティーの並び順に何かあるのかと思い込んでました。

ターゲットの最後尾が使用者になれば全員に表示されるということなので
使用者の決定プロセスを変更して対応することにします。

コード: 全て選択

   Scene_Item.prototype.user = function() {
      const members = $gameParty.movableMembers();
      const bestPha = Math.max(...members.map(member => member.pha));
//      return members.find(member => member.pha === bestPha);
      return members.filter(member => member.pha === bestPha).pop();
   };
Twitter、はじめました。
https://twitter.com/wtr_in_reverie/
アバター
Plasma Dark
記事: 669
登録日時: 2020年2月08日(土) 02:29
連絡を取る:

Re: 【解決】メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by Plasma Dark » 2023年1月14日(土) 18:01

bestPhaでフィルタかけてしまうと、ターゲットの最後尾以外が使用者になり得ると思うのですが、大丈夫でしょうか。
(薬の知識などでphaを変動させないなら動作上問題はないですが、その場合も別にフィルタする処理は必要なさそうです。単にパーティの末尾にいるアクターを使用者としてしまうのが楽だと思います)

あるいは、ちょっと乱暴ですが、applyItemの流れの間だけ、clearResultを何もしないように置き換えてしまうとか。

コード: 全て選択

  const _applyItem = Scene_ItemBase.prototype.applyItem;
  Scene_ItemBase.prototype.applyItem = function() {
    const _crearResult = this.user().clearResult;
    this.user().clearResult = () => {};
    _applyItem.call(this);
    this.user().clearResult = _crearResult;
  };


追記: clearResultを単に置き換えるだけだと、使用者のresultが残ってしまい、なんか変なこと起きそうな気がするので、ダメージポップアップが確定したタイミング辺りでclearしてあげるほうが良さそうです。

コード: 全て選択

  const _setup = Sprite_Damage.prototype.setup;
  Sprite_Damage.prototype.setup = function (target) {
    _setup.call(this, target);
    if (!$gameParty.inBattle()) {
      target.result().clear();
    }
  };


更に追記: chroさんの仰る通り、連続回数でおかしなことになるので、applyItem内で次のアクターにapplyする前にsetupDamagePopupを呼び出してしまうのが良さそうです。
最後に編集したユーザー Plasma Dark on 2023年1月15日(日) 10:08 [ 編集 1 回目 ]
アバター
WTR
記事: 559
登録日時: 2015年12月22日(火) 19:14

Re: 【解決】メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by WTR » 2023年1月14日(土) 19:18

ご指摘ありがとうございます。
言われてみれば意味のないフィルタでした。
薬の知識を運用することはたぶんないと思いますが
$gameParty.movableMembers() もよくない気がしてきたので純粋にパーティーの最後尾にしようと思います。

薬の知識を持っているメンバーが倒れていたりすると、薬の知識は反映されないという動きになっているのかな
なかなか凝った仕組みで難解…
Twitter、はじめました。
https://twitter.com/wtr_in_reverie/
chro
記事: 86
登録日時: 2021年2月14日(日) 11:26

Re: 【解決】メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by chro » 2023年1月14日(土) 21:39

一応アイテムだけではなく、回復スキルの場合もあります。

仕様上は、敵全体に【HP吸収スキル】を使用した場合、対象のHPダメージと使用者のHP回復があります。
その為、使用者に反映されていないような現象となっています。

きっちり実装すると、ここで追加するのが良さそうです。
連続回数も反映されます。

コード: 全て選択

Scene_ItemBase.prototype.applyItem = function() {
    const action = new Game_Action(this.user());
    action.setItemObject(this.item());
    for (const target of this.itemTargetActors()) {
        for (let i = 0; i < action.numRepeats(); i++) {
            action.apply(target);
            //追加
            target.startDamagePopup();
            const sprite = this._actorWindow._actorSprite.find(sprite => sprite._actor === target);
            if (sprite) sprite.setupDamagePopup();
        }
    }
    action.applyGlobal();
};


もう一点、アイテム画面の場合、全回復するまで連打をします。
ポップアップの表示位置も調整しないと、連打して連続使用した場合、ズレてきます。

コード: 全て選択

Sprite_Battler.prototype.createDamageSprite = function() {
    const last = this._damages[this._damages.length - 1];
    const sprite = new Sprite_Damage();
    if (last) {
        sprite.x = last.x + 8;   //ポップアップ表示位置
        sprite.y = last.y - 16; //ポップアップ表示位置
    } else {
        sprite.x = this.x + this.damageOffsetX();
        sprite.y = this.y + this.damageOffsetY();
    }
    sprite.setup(this._battler);
    this._damages.push(sprite);
    this.parent.addChild(sprite);
};
アバター
WTR
記事: 559
登録日時: 2015年12月22日(火) 19:14

Re: 【解決】メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by WTR » 2023年1月14日(土) 23:30

ありがとうございます。参考にします。
全体HP吸収スキルのため、と聞いた今をもってして
コアスクリプトの実装からその意図を読み取れる感触はない…

アイテム・スキル回り、かなり複雑なことしてるんだな、と実感しています。
Twitter、はじめました。
https://twitter.com/wtr_in_reverie/
chro
記事: 86
登録日時: 2021年2月14日(日) 11:26

Re: 【解決】メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by chro » 2023年1月15日(日) 01:18

実際の戦闘中の推移を比較すればわかりやすいです。
この辺りは、コアスクリプトだけだと意図は掴みにくいです。

敵全体からHP吸収するアイテム・スキルを使用した場合です。
hpdrain1.png

hpdrain2.png


対象が全体であっても、個別にダメージポップアップされ、HP吸収等は使用者に(35→39)のように表示されます。

ダメージポップアップは、Window_BattleLogで制御されています。

コード: 全て選択

Window_BattleLog.prototype.popupDamage = function(target) {
    if (target.shouldPopupDamage()) {
        target.startDamagePopup();
    }
};


今回は単にHP吸収等をしていないので、使用者は表示されていないだけです。
最後尾だと、使用者と対象者が同じになります。

本来の戦闘中のダメージポップアップは、個別に表示されていたため、
Scene_ItemBaseで利用するには、
Sprite_Battler.prototype.setupDamagePopup
を戦闘中と同じように呼び出す必要があります。
アバター
WTR
記事: 559
登録日時: 2015年12月22日(火) 19:14

Re: 【解決】メニューでアイテム使用時、回復量のポップアップ表示をしたい

投稿記事by WTR » 2023年1月15日(日) 02:09

詳細までありがとうございます。

Window_BattleLog がポップアップ制御するのですか…

戦闘の流れはちょっとだけ弄って放置してあるのですが
Window_BattleLog の責務が想像以上に広くて混乱した記憶はあります。
名前から受動的な一方的に制御される対象というイメージを持っていたのですが全然違った…
BattleManager と Scene_Battle は結構追いかけたのですが
本格的に戦闘を弄ろうとすると Window_BattleLog は課題になりそうな気がしています。
Twitter、はじめました。
https://twitter.com/wtr_in_reverie/

“MZ:質問” へ戻る