【プラグイン不具合・解決済み】MNKR_HenshinMZの表示について

大鳥椎名

ユーザー
ムノクラ様。
便利なプラグインを製作して頂き、ありがとうございます。
MNKR_HenshinMZを導入し、装備の切り替えを行うスキルを作っています。
プラグインの説明にもある通り、戦闘中にも使用できるプラグインなのですが、これを戦闘中に使用すると、その戦闘中はアクターの『フェイス画像』『アクター名』『HP』『MP』『TP』が更新されず、パーティから抜けたアクターのものが表示され続ける現象を確認しています。
アクターの入れ替えには成功しているので、表示のみの不具合のようです。

フォーラムに投稿されていないプラグインでしたので、こちらとQ&Aのどちらに投稿すべきか迷いましたが、まずはこちらに投稿させて頂きました。
無償で提供して頂いている中で申し訳ないのですが、お時間のあるときに確認してはいただけないでしょうか。ご検討よろしくお願いします。
 

munokura

ユーザー
大変ご迷惑をおかけしております。

こちらのプラグインは思いつきで作った、実験的簡易なコードです。

コードが分かる人が見たら「まぁ、そうなるよね」という内容です。

$gameMap.requestRefresh();
でマップ上での表示内容更新はされているはずなのですが、戦闘画面は想定していませんでした…

「見てらんねーな」という上級者のアドバイスを期待しつつ、これから方法を調べます。


独り言
 戦闘中にアクターを入れ替えるプラグインのコードとか読んだら、ヒントになりますかね?
 

chronicle

ユーザー
根本的にはGame_PartyaddActorswapOrderremoveActorの順番(追加→並び替え→削除)でメソッドを呼ぶしかないですね。
他はアクターID & 変身前加入済み & 変身後未加入の判定です。
追記:エネミーの変身Game_Enemy.prototype.transformと同じようにGame_Actorで実装しただけで、プラグインコマンド内でも問題はないです。
根本的にと言うのは、コアスクリプトのバージョンアップ後や他のプラグイン導入時も必ず動くようにするためです。

表示だけでなく、_actorsプロパティを書き換えただけだと、戦闘行動開始や終了もなくおかしなことになります。
わかりやすいものだと、戦闘終了後に解除されるステートは残ったままになるとか。

追記2:戦闘メンバー数によって正しく動作しないため、戦闘メンバー扱いになるよう修正しました。

コード:
(function() {
  'use strict'

  const pluginName = document.currentScript.src.split("/").pop().replace(/\.js$/, "");

  PluginManager.registerCommand(pluginName, "henshin", args => {
    const actor = $gameActors.actor(Number(args.ActorId1));
    if (actor) actor.transform(Number(args.ActorId2));
  });

  Game_Actor.prototype.transform = function (actorId) {
    const allMemberIndex = actor => $gameParty.allMembers().indexOf(actor);
   
    const index = allMemberIndex(this);
    const transformActor = $gameActors.actor(actorId);
    let transformIndex = allMemberIndex(transformActor);
    if (!transformActor || index < 0 || transformIndex >= 0) return;

    const wasBattleMember = $gameParty.battleMembers().includes(this);
    if (wasBattleMember) $gameParty._transformActorId = actorId;
    $gameParty.addActor(actorId);
    transformIndex = allMemberIndex(transformActor);
    if (transformIndex >= 0) {
      $gameParty.swapOrder(index, allMemberIndex(transformActor));
      if (wasBattleMember) $gameParty._transformActorId = this.actorId();
      $gameParty.removeActor(this.actorId());
    }
    $gameParty._transformActorId = null;
  };

  const _Game_Party_initialize = Game_Party.prototype.initialize;
  Game_Party.prototype.initialize = function () {
    _Game_Party_initialize.apply(this, arguments);
    this._transformActorId = null;
  };

  const _Game_Party_battleMembers = Game_Party.prototype.battleMembers;
  Game_Party.prototype.battleMembers = function() {
    const members = _Game_Party_battleMembers.apply(this, arguments);
    if (this._transformActorId) members.push($gameActors.actor(this._transformActorId));
    return members;
  };

})();
 
最後に編集:

munokura

ユーザー
>>chronicle氏
ちょっと実験して、どうしてこの状況になったのかを思い出しました。

最初はMVで作成しました。

その時の動作確認では「戦闘中でもアクターの表示に異常が見られなかった」ので、「これで動くのか…」と思ってしまいました。
それでヘルプにそのように書きました。

その時は、まだ「メソッドを使用しないでプロパティを直接書き換えると問題が起こる事があり、非推奨である」という認識がありませんでした。
(これはプラグインの作り方シリーズの記事を順次書いている途中で、多くの方から指摘・補助となる記事を拝見して学習しました)

ついでに「プラグインコマンドを書き換えるだけだから、MZにもしておこう」くらいのつもりで、移植したものをアップしていました。
多分、この時に戦闘中のテストをしなかったのでしょう。

そんなわけで、今ならchronicle氏に提示いただいたコードの意味が理解できますし、「完全に作り直し」する理由が分かります。
今は「なぜ、MVで動いていた?」という疑問があります…

>>大鳥椎名氏
chronicle氏に提示いただいたコードに全面差し替えしたプラグインをGitHubにアップしました。

こちらをご使用ください。
 

大鳥椎名

ユーザー
>>chronicle氏
ちょっと実験して、どうしてこの状況になったのかを思い出しました。

最初はMVで作成しました。

その時の動作確認では「戦闘中でもアクターの表示に異常が見られなかった」ので、「これで動くのか…」と思ってしまいました。
それでヘルプにそのように書きました。

その時は、まだ「メソッドを使用しないでプロパティを直接書き換えると問題が起こる事があり、非推奨である」という認識がありませんでした。
(これはプラグインの作り方シリーズの記事を順次書いている途中で、多くの方から指摘・補助となる記事を拝見して学習しました)

ついでに「プラグインコマンドを書き換えるだけだから、MZにもしておこう」くらいのつもりで、移植したものをアップしていました。
多分、この時に戦闘中のテストをしなかったのでしょう。

そんなわけで、今ならchronicle氏に提示いただいたコードの意味が理解できますし、「完全に作り直し」する理由が分かります。
今は「なぜ、MVで動いていた?」という疑問があります…

>>大鳥椎名氏
chronicle氏に提示いただいたコードに全面差し替えしたプラグインをGitHubにアップしました。

こちらをご使用ください。

根本的にはGame_PartyaddActorswapOrderremoveActorの順番(追加→並び替え→削除)でメソッドを呼ぶしかないですね。
他はアクターID & 変身前加入済み & 変身後未加入の判定です。
追記:エネミーの変身Game_Enemy.prototype.transformと同じようにGame_Actorで実装しただけで、プラグインコマンド内でも問題はないです。
根本的にと言うのは、コアスクリプトのバージョンアップ後や他のプラグイン導入時も必ず動くようにするためです。

表示だけでなく、_actorsプロパティを書き換えただけだと、戦闘行動開始や終了もなくおかしなことになります。
わかりやすいものだと、戦闘終了後に解除されるステートは残ったままになるとか。

コード:
(function() {
  'use strict'
  const pluginName = document.currentScript.src.split("/").pop().replace(/\.js$/, "");

  PluginManager.registerCommand(pluginName, "henshin", args => {
    const actor = $gameActors.actor(Number(args.ActorId1));
    if (actor) actor.transform(Number(args.ActorId2));
  });

  Game_Actor.prototype.transform = function (actorId) {
  //存在するアクターID & 変身前加入済み & 変身後未加入
    const index = $gameParty.allMembers().indexOf(this);
    const transformActor = $gameActors.actor(actorId);
    let transformIndex = $gameParty.allMembers().indexOf(transformActor);
    if (!transformActor || index < 0 || transformIndex >= 0) return;

    $gameParty.addActor(actorId);
    transformIndex = $gameParty.allMembers().indexOf(transformActor)
    if (transformIndex >= 0) {
      $gameParty.swapOrder(index, transformIndex);
      $gameParty.removeActor(this.actorId());
    }
  };
})();

ムノクラ様、chronicle様。
早急に対応して頂き、ありがとうございます。
新しいバージョンでの動作確認が終わりました。

忍者がたくさん出てくる作品を作っていたので、任意のタイミングでの変装解除はどうしても実装したい機能の1つでした。
chronicle様の指摘にもありました、戦闘終了時のステート解除が実行されず残るという点は、並列処理のコモンイベントなどで対応していこうと思います。
問題解決に向けて対応とご意見を頂き、ありがとうございました。
 

chronicle

ユーザー
すいません、このままだと不完全で、戦闘メンバー数が最大の場合に待機メンバー扱いになってしまうため正しく戦闘処理が行われません。
修正したものに差し替えました。
変身した時点で、そのアクターは戦闘状態の開始・終了になるので、戦闘終了時のステートも解除されます。
 

大鳥椎名

ユーザー
すいません、このままだと不完全で、戦闘メンバー数が最大の場合に待機メンバー扱いになってしまうため正しく戦闘処理が行われません。
修正したものに差し替えました。
変身した時点で、そのアクターは戦闘状態の開始・終了になるので、戦闘終了時のステートも解除されます。
度重なるご対応、ありがとうございます!
差し替えて頂いたコードのダウンロード先は、ムノクラ様が提示した以下のURLでよろしいでしょうか?

>>大鳥椎名氏
chronicle氏に提示いただいたコードに全面差し替えしたプラグインをGitHubにアップしました。

こちらをご使用ください。

(追記)
chronicle様の提示したコードが更新されているのを確認しましたので、バックアップをとってからこのコードをプラグインに一度代入してみますね。
 

大鳥椎名

ユーザー
すいません、このままだと不完全で、戦闘メンバー数が最大の場合に待機メンバー扱いになってしまうため正しく戦闘処理が行われません。
修正したものに差し替えました。
変身した時点で、そのアクターは戦闘状態の開始・終了になるので、戦闘終了時のステートも解除されます。
最新のスクリプトの動作確認が完了しました。
入れ替えの際にステートの解除まで確認できました。細かな部分まで配慮して頂き、ありがとうございます。
 
最後に編集:
トップ