そのターンにおける、アクターの技を真似するエネミーを作りたい

まるお

ユーザー
技ごとにステートを作り、それを消化するように行動の強制をコモンイベントで行うという方法を考えていましたが、これではイベント数が多くなり、管理が大変です。

これをスクリプト等を使ってアクターのスキル情報を保存し、それに適合する番号のスキルで行動の強制を行うといったことはできないでしょうか?
 

まるお

ユーザー
行動の強制をスクリプトで行う場合ですと、スキルidを変数で指定できることがわかりました。
現時点での問題点はあと、4人分のアクターのスキルidをどのようにして取得するかという点のみです。
 

タシラカ

ユーザー
どうもこんにちは。
もう少し仕様を整理してもらわないと答えるのは難しい気がしますね。

まずスキル情報の保存について。
これは直前のアクターの行動のみ保存すれば良いのか、
あるいはターン中のアクターの行動全て保存すれば良いのか、
また「行動」とは通常攻撃や防御、アイテムは含めないのか?

それと「行動の強制をコモンイベント」というのはスキルの使用効果「コモンイベント」の事ですか?
総じて「ターン開始時からエネミーが行動するまでのアクターが使用した特殊スキルを全て記録し、
当該エネミーの行動時に記録したスキルを対象ランダムで全て使用するスキルを作りたい」という事でしょうか?
 

まるお

ユーザー
行動の強制は、バトルコマンドの戦闘行動の強制のことです。

保存内容はターン中のアクターのスキルです。

アクターのスキルを変数として保存し、その番号と同様のスキルをエネミーが戦闘行動の強制により真似をするという流れです。

現時点でやりたいことは、ターン中のアクターの行動内容を保存するということのみです。
 

タシラカ

ユーザー
あーなるほど?
つまりバトルイベントのスパン「モーメント」あたりで
アクターがスキルを使用する度に割り込みで同じスキルの強制行動を発生させたい、という事ですか?

それと「行動の強制をスクリプトで行う」というのはcommand339に記述されているコード
JavaScript:
    this.iterateBattler(this._params[0], this._params[1], function(battler) {
        if (!battler.isDeathStateAffected()) {
            battler.forceAction(this._params[2], this._params[3]);
            BattleManager.forceAction(battler);
            this.setWaitMode('action');
        }
    }.bind(this));
この部分をイベントコマンド>スクリプトから実行する事を想定している、という事でしょうか?
質問ばかりで恐縮ですが事前に情報をすり合わせないと適切な回答を出来る可能性は低いです
 
最後に編集:

温州みかん

ユーザー
こちらで紹介されているプラグインを利用して、使用したスキルIDを「指定した任意の変数」に取得し


こちらの方法(タシラカさんが紹介されているコードと同じですが)で、バトルイベントの「戦闘行動の強制」を スクリプトで記述し
4行目のスキルIDのところに、「指定した任意の変数の値」を示す 「$gameVariables.value(n)」 を入れれば可能かと思われます
nは「指定した変数の変数」値 変数10にあてがっていたなら「$gameVariables.value(10)」

リンク先の例では例としてスキル:ファイアのスキルID「9」を直接指定していますが、その代わりに上の「」内の文字列を入れればできると思います(未検証)
 

まるお

ユーザー
ご紹介いただいた、スキルを保存するプラグインTkoolMV_PluginCommandBook.jsを利用したところ次のようなエラーが出ました。キャプチャ.JPGキャプチャ.JPG

プラグインをオフにすると何事もなかったかのように動作します。
プログラミング初心者でよくわからないのですが、これはいったい何が原因でこのようなエラーが出ているのでしょうか?
 

まるお

ユーザー
あーなるほど?
つまりバトルイベントのスパン「モーメント」あたりで
アクターがスキルを使用する度に割り込みで同じスキルの強制行動を発生させたい、という事ですか?

それと「行動の強制をスクリプトで行う」というのはcommand339に記述されているコード
JavaScript:
    this.iterateBattler(this._params[0], this._params[1], function(battler) {
        if (!battler.isDeathStateAffected()) {
            battler.forceAction(this._params[2], this._params[3]);
            BattleManager.forceAction(battler);
            this.setWaitMode('action');
        }
    }.bind(this));
この部分をイベントコマンド>スクリプトから実行する事を想定している、という事でしょうか?
質問ばかりで恐縮ですが事前に情報をすり合わせないと適切な回答を出来る可能性は低いです
処理内容についてはその解釈であっていますが、
イベントを発生させるタイミングは、スキル使用時です。
1594777153308.png
現在はステート式となっていますが、こちらを新しいものに置き換える予定です。
 
最後に編集:

まるお

ユーザー
イメージはプラグイン等でアクター全員のスキルIDを格納し、
ものまねが不可能なスキル(アクターのみが使用することを想定して作成されたスキル)がIDで指定された場合は、
変数に2を代入しスクリプトを実行させません。
それ以外の場合は、スクリプトよりあらかじめパーティーそれぞれで保存したスキルを戦闘行動の強制よりエネミーに行わせるということです。

例1)
パーティー1 攻撃
パーティー2 ファイア
パーティー3 防御
パーティー4 攻撃

エネミーのターン
ものまねより
攻撃、ファイア、攻撃を使用

例2)
パーティー1 防御
パーティー2 防御
パーティー3 アイテム使用
パーティー4 防御

エネミーのターン
参照できる情報が2なのでエネミーにステート付加
エネミーはHP再生率-5よりそのターンだけダメージ(ここの設定は既に設定が完了しています)
なお、2であるかどうかはスキル保存という変数が2の時に随時追加していきます。


キャプチャ.JPG
1594775953399.png
 

タシラカ

ユーザー
リンク先の例では例としてスキル:ファイアのスキルID「9」を直接指定していますが、その代わりに上の「」内の文字列を入れればできると思います(未検証)
中身も見て検証してみましたが、残念ながら流用は難しそうですね。
詳細は割愛させていただきます。

イメージはプラグイン等でアクター全員のスキルIDを格納し、
ものまねが不可能なスキル(アクターのみが使用することを想定して作成されたスキル)がIDで指定された場合は、
変数に2を代入しスクリプトを実行させません。
それ以外の場合は、スクリプトよりあらかじめパーティーそれぞれで保存したスキルを戦闘行動の強制よりエネミーに行わせるということです。
説明ご苦労様です。
FF5のものまね士ゴゴみたいにカウンター寄りに即時発動させるんではなく
ターン中のスキルを全てスタックして、それを全て使用する形を想定しているんですね。
色々と検討したけど簡易プラグイン作らないと実装は無理っぽいですね。
スキルIDの保存もそうなんですけど、強制行動を実行すると入力済の行動がキャンセルされる仕様の為
スキルの連続実行を視野に入れる場合はその点にも留意する必要があります。今回は配列に対応した関数を用意します。

こちらが必要最小限だと思うプラグインです。
適当なテキストファイルにコピペした後に〇〇.jsと付けてプラグインマネージャに登録してください。
JavaScript:
"use strict";
{
    BattleManager.clearUsedSkillList = function() {
        this._usedSkillList = [];
    };
    BattleManager.usedSkillList = function() {
        return this._usedSkillList;
    };
    const OLD_INIT_MEMBERS = BattleManager.initMembers;
    BattleManager.initMembers = function() {
        OLD_INIT_MEMBERS.call(this);
        this.clearUsedSkillList();
    };
    const OLD_END_TURN = BattleManager.endTurn;
    BattleManager.endTurn = function() {
        OLD_END_TURN.call(this);
        this.clearUsedSkillList();       
    };
    const OLD_START_ACTION = BattleManager.startAction;
    BattleManager.startAction = function() {
        OLD_START_ACTION.call(this);
        if (this._subject.isEnemy()) return;
        if (this._action.isItem()) return;
        this._usedSkillList.push(this._action.item().id);
    }
    Game_Battler.prototype.forceActionEx = function(skillList, targetIndex) {
        this.clearActions();
        skillList.forEach((skillId) => {
            const action = new Game_Action(this, true);
            action.setSkill(skillId);
            if (targetIndex === -2) {
                action.setTarget(this._lastTargetIndex);
            } else if (targetIndex === -1) {
                action.decideRandomTarget();
            } else {
                action.setTarget(targetIndex);
            }
            this._actions.push(action);
        });
    };
}
コモンイベントに張り付けるスクリプトはこんな感じですね
JavaScript:
// 除外スキルIDリスト
const exclusionList = [2]; // [2, 3, 4, 5]
const skillList = BattleManager.usedSkillList().filter((skillId) => { 
    return !exclusionList.includes(skillId);
}); 
$gameSwitches.setValue(101, 0 < skillList.length); // 物まね成功フラグ
if (0 < skillList.length) {
    const battler = BattleManager._subject;
    battler.forceActionEx(skillList, -1); // -1は対象不定
    BattleManager.forceAction(battler);
    this.setWaitMode('action');
}
書いてて妙に煮詰まったのでどこから説明するべきか迷うのですが
JavaScript:
const exclusionList = [2]
に除外リストを作ったので、防御を始めとして物まねしたくないスキルIDを配列形式で入力してください。
JavaScript:
$gameSwitches.setValue(101, 0 < skillList.length); // 物まね成功フラグ
それと物まねに成功したかどうかを受け取るフラグを作ったので、こちらの方でステート付与の判定を作ると良いでしょう。
現時点だとスイッチ番号101番に仮当てしています。他は弄る必要ないかな?
イメージと違うようなら気軽にどうぞ。局所的に凝り性なので気になります。
 

温州みかん

ユーザー
>タシラカさま 
余計な口出しをしてしまったようです

ご紹介いただいた、スキルを保存するプラグインTkoolMV_PluginCommandBook.jsを利用したところ次のようなエラーが出ました。View attachment 8078View attachment 8079

プラグインをオフにすると何事もなかったかのように動作します。
初心者でよくからないのですが、これはいったい何が原因でこのようなエラーが出ているのでしょうか?
おそらく他のプラグインとの競合です (最近のプラグインではないので、バージョンエラー的な不具合である可能性もあります)
TkoolMV_PluginCommandBook は制御文字やプラグインコマンドを制御、拡張する複合プラグインで、そのなかのひとつにスキルIDを取得する機能があります エラーは Spriteクラスの定義領域 のところで引っかかっているようです 「isAnimationPlayingの(プロパティ)値が見つからない」そんなオブジェクトがそもそも存在しないのか、戻り値が設定されていないのか、ただの誤字なのか(よく私がやるやつ)……詳細についてはわかりません

ダイレクトに「ものまね」できる、最適化されたものをタシラカさんが組まれているので、そちらでしたら競合のおそれが限りなく小さいと考えます
 
トップ