開発日誌

プラグイン/スクリプト

[ テクニック ] [ 素材 ] [ プラグイン/スクリプト ] ダメージ計算式内のスクリプトが自動戦闘で実行されるのを防ぐ

2022-03-21 16:11:50

スキルやアイテムのダメージ計算式内に、ダメージ計算以外のスクリプトを書いた際に、自動戦闘の評価時にもそれが実行されてしまうのを防ぐプラグインを作成しました。

RPGツクールMV/MZの両方に対応しています。

ダメージ計算式の応用テクニック

スキルやアイテムのダメージ計算式にはスクリプトを記述することができ、ダメージ計算式以外の処理をさせることができます。

例えば「体当たり」という、敵に大ダメージを与える代わりに、自分がスタンしてしまうスキルを考えます。

このような、相手にダメージを与えつつ、自分にも何らかの効果を及ぼすようなスキルは、標準では作れません。RPGツクールMZであれば、新たに導入された「直前に行動したアクターのID」や「直前に行動した敵キャラのインデックス」を用いて、コモンイベントでステートを付与することも可能ですが、味方はともかく敵キャラのスキルとしても対応させようとすると、けっこう面倒くさいです。

しかし、RPGツクールMVでも可能で、かつ簡易な方法があります。

それが、ダメージ計算式を応用する方法です。

ダメージ計算式の中はスクリプトが書けるようになっており、かつスキルの使用者がa、対象者がbで表せるようになっています。

通常の使い方としては、a.atkで使用者の攻撃力を取得したり、b.defで対象者の防御力を取得したりするものですが、aやbの実体はGame_ActorやGame_Enemyオブジェクトなので、それらが持つプロパティやメソッドは全て使用することができます。

すなわち、a.addState(10)と書けばスキルの使用者に10番のステートを付与することができますし、a.increaseBuff(4)と書けばスキルの使用者の魔法力を1段階上げることができます。

前述の「体当たり」スキルであれば、

a.addState(13); a.atk * 4

と書くことで、自身の攻撃力の4倍のダメージを相手に与えつつ、代わりに自分が13番のステート(スタン)にかかります。

正攻法ではありませんが、このダメージ計算式にスクリプトを埋め込む方法は、応用技としてよく用いられており、当サイトでも「プラグインなしでムチ攻撃」などの記事で紹介しています。

自動戦闘での問題点

しかし、このダメージ計算式の応用技は自動戦闘の際に問題があります。

アクターや職業、武器の特徴では「特殊フラグ」の「自動戦闘」というのがあり、この特徴が付くと自動的に戦ってくれるようになります。

この自動戦闘の仕様はどういうものかというと、その時に使用可能な全てのスキルを使った時のダメージ量を計算して、ダメージ総量のより多いスキルが選ばれるようになっています。

つまり、最初に全てのスキルに関してダメージ計算を行うため、ダメージ計算式内のスクリプトが実行され、ステート付与など結果を伴うスクリプトの内容が実際に反映されてしまうのです。

本プラグインはこの問題を解消し、自動戦闘におけるダメージ量評価時には、スクリプトの内容が反映されないようになります。

プラグインの実装

具体的にどうやっているのかというと、aにスキルの使用者、bに対象者を代入する際、自動戦闘の評価時には、ツクールのコアスクリプトで定義されているJsonEx.makeDeepCopy()を用いて、使用者と対象者そのものではなく、それのコピーを代入するようにしています。本体ではなくコピーなので、実際のアクターや敵キャラには影響を及ぼしません。

同様にダメージ計算式においては、itemに使用するスキルやアイテム、vに変数が代入されますが、これらもコピーを代入するようにしているので、例えばダメージ計算式内で変数を操作したとしても、実際の変数が変化することはありません。

グローバル変数「inEval」

多くの場合は以上で解決するのですが、場合によってはこれだけでは解決しないケースがあります。

例えば自爆技のように、自分の命と引き換えに、敵に大ダメージを与えるスキルの場合、ダメージ計算式を以下のようにすれば、とりあえず目的は達成することができます。

a.die(); 300

上記の例では、a.die()で使用者を戦闘不能状態にさせつつ、敵に300ポイントのダメージを与えることができます。

ただこれだと、使用者に戦闘不能のステートが付くだけで、死亡時のエフェクトがないため、自爆したことが分かりづらいです。

performCollapse()で死亡時のエフェクトを演出することができるので、ダメージ計算式を下記のようにしてみましょう。

a.die(); a.performCollapse(); 300

これでちゃんと死亡時のエフェクトが出るようになりましたが、自動戦闘にすると評価時にも死亡時のSEが鳴ってしまいます。

本体ではなくコピーを使うことで、ステートの変化が実際に反映されることはなくなりましたが、SEやアニメーションなどはその限りではありません。

というわけで、自動戦闘の評価時か否かを表すグローバル変数「inEval」を定義しました。

inEvaltrueであれば自動戦闘の評価時、falseであれば実際のスキルの使用時となり、ダメージ計算式内で分岐させることができます。

a.die(); !inEval && a.performCollapse(); 300

上記のように書けば、自動戦闘の評価時にはa.performCollapse()が実行されず、実際の使用時にのみ実行されるようになります。

変数名として「inEval」を使っているプラグインとは競合する可能性がありますので、ご注意ください。

質問やアドバイスなどはコメント欄まで、お気軽にお願いします。素材利用条件などについては、このサイトについての「提供素材について」の項目などをご覧ください。

[ テクニック ] [ 素材 ] [ プラグイン/スクリプト ] バフ・デバフに連動してステート付与

2022-03-09 03:27:14

能力値の強化・弱体の状態に応じて自動的に特定のステートを付与してくれるプラグインを作成しました。

例えば魔法も物理攻撃もしてくる敵キャラで、攻撃力が強化されている時は物理攻撃ばかりするようになったり、自分の能力値が下げられている時はそれを解除するような行動をしたり、ということをさせたい場合、RPGツクールVXの時は能力値の強化・弱体もステートの一種だったため、普通に行動条件に強化や弱体のステートを指定すれば実現できました。

しかしVX Ace以降、MV、MZは、強化・弱体が2段階かけられるようになった代わりにステートとは別枠の扱いとなったため、行動パターンの条件に使うことができなくなったばかりか、強化・弱体の状態を直接取得する手段もスクリプト以外には存在しないため、変数に現在の能力値を取得して、それがいくつかを敵キャラ個別に判定するという、気の遠くなるような実装が必要となってしまいます。

そこで、能力値の強化(バフ)・弱体(デバフ)の状態に応じて、自動的にステートを付与してくれるプラグインを作成しました。

また強化と弱体だけでなく、どちらもかかっていない、すなわち元の能力値の場合である時にステートを付与することもできます。これによって、攻撃力が強化されていない時に限って攻撃力上昇の魔法を使ったり、といった行動パターンの制御が可能になります。

RPGツクールMV/MZの両対応です。

事前準備が少々複雑なので、説明をよく読んでお使いください。

※ 2022-03-12追記:
デバフステートの処理にバグがあったので修正しました。お手数ですが、Version.1.0.1にアップデートをお願いします。

ステートの作成

まずは強化・弱体・通常の各状態を表すステートを作成します。

デフォルトのシステムでは、最大HP・最大MP・攻撃力・防御力・魔法力・魔法防御・敏捷性・運の8つの能力値に、強化と弱体がそれぞれ2段階ずつ、それに加えて能力値が通常(強化も弱体もかかっていない状態)のステートが必要なので、全部で40個のステートを作成する必要があります。

弱体のステートは必要ないとか、通常のステートは必要ない、といった場合は省略することができますが、特定の能力値だけ省略するといったことはできません。必ず全能力値分のステートを作成する必要があります。(厳密に言うと、不要な能力値であればステート名を付ける必要はありませんが、ステートの枠としては確保しておく必要があります。)

プラグイン等で能力値の数や強化の段階を変更している場合は、その分だけステートを作成する必要があります。

ステートの順序は、強化・弱体状態を表すアイコンの順序と同じです。

すなわちデフォルトでは、強化であれば最大HPの強化1段階、最大MPの強化1段階……の順で、最後は敏捷性の強化2段階、運の強化2段階、の順で終わります。弱体も同様です。

通常状態には段階がありませんが、能力値の順序は同様で、最大HPの通常時、最大MPの通常時……運の通常時の順にステートを作成します。

プラグイン等で強化・弱体の仕組みを変更している場合は、アイコンの順序を参考にステートを作成してください。

ダミーステートなので、ステートの設定は特に不要です。

ステート名を設定するのと、あとは「戦闘終了時に解除」にチェックしておけば、戦闘でない時に余計なステートが付かなくて済みます。

ステートアイコンはテスト時以外は設定しない方がよいでしょう。メッセージ等も不要です。

プラグインパラメータの設定

ステートの作成が終わったら、次はプラグインパラメータの設定です。

「強化開始ステート」「弱体開始ステート」「通常開始ステート」で、それぞれ強化、弱体、通常状態の先頭(最大HP)のステートを指定します。

弱体のステートは必要ないとか、通常のステートは必要ない、といった場合は指定を「なし」にすればOKです。

「強化最大段階」「弱体最大段階」で、それぞれ強化・弱体が最大で何段階まであるかを指定します。デフォルトは2で、プラグイン等で変更している場合はその段階数を指定します。本プラグインに段階数を変更する機能はありません。

「低段階ステート付与」をON(true)にすると、例えば攻撃力強化2段階が付いた場合に、攻撃力強化1段階のステートも同時に付与されます。OFF(false)にすると、攻撃力強化2段階の場合は2段階のステートのみが付与され、1段階のステートは付与されません。

強化・弱体がかかっていれば、何段階かにかかわらず特定の行動をとらせたい、といった場合にはONにすると便利です。

敵キャラの行動パターンの設定

以上で事前準備が完了したら、本題の敵キャラの行動パターン設定に移ります。

行動パターンの条件のステートで、強化・弱体・通常が使えるようになるので、それらを駆使して効果的な行動パターンを作成してください。

想定している使い方としては、例えば以下のようなものがあります。

  • 「攻撃力通常」の場合にのみ攻撃力強化のスキルを使用する
  • 「攻撃力強化」の場合は通常攻撃のみしてくる
  • 「攻撃力弱体」の場合は魔法攻撃のみしてくる
  • 「攻撃力弱体」の場合は弱体解除のスキルを使用する

敵のバフ・デバフ行動は、深く考えずに作ると無駄撃ちが多くなりがちなので、このバフ・デバフ連動ステートを使って、賢い(いやらしい)敵キャラを作ってみてください。

プラグインの実装と注意点

今回のプラグインは、事前準備が少々面倒で分かりにくい部分があるので、不明点等あればお気軽にお問い合わせください。

特に、他のプラグインで能力値の数や強化の段階を変更している場合は、どのようにステートを準備すればいいかが分かりにくいかもしれません。

プラグインの実装としては、Game_BattlerBase の buffIconIndex を利用して、基準値(最大HPの強化・弱体1段階)からのインデックスを取得し、何番目のステートかを計算させています。

能力値や強化の段階を変更している場合は、当該プラグインが強化・弱体状態を表すアイコンのインデックスを、どのように取得しているかに準拠しますので、これを参考にステートを作成してください。

また機能として、強化も弱体もかかっていない状態を表すステートと、高段階の強化・弱体がされている時に低段階のステートも付与するオプションは、想定する用途があったので追加しましたが、他にも付随する機能で欲しい機能があれば、ご相談ください。ただし、あまりに個別の用途だったり、仕様が複雑になりすぎる機能だったりする場合は、ご希望に添えない場合もありますので、ご了承ください。

その他、質問やアドバイスなどはコメント欄まで、お気軽にお願いします。素材利用条件などについては、このサイトについての「提供素材について」の項目などをご覧ください。

[ テクニック ] [ 素材 ] [ プラグイン/スクリプト ] 敵キャラの行動パターンに複数条件を指定

2022-02-11 14:54:11

敵キャラの行動パターンに複数の条件を指定できるようにするプラグインを作成しました。

これによって、残りHPが少なくてかつ特定ターンに限り強力な回復魔法を使ってくる敵とか、こちらのパーティーのレベルに応じて行動のローテーションが変化していくような敵を、バトルイベントでの制御やメモ欄での複雑な記述なしに作ることができます。

RPGツクールMV/MZの両方に対応しています。

行動パターンの条件指定

敵キャラの行動パターンには、ターン数や自身のHP/MPの範囲、かかっているステート、パーティーの平均レベルがいくつ以上、およびスイッチと、様々な発動条件を指定することが可能です。

しかし、これらの条件は1つの行動パターンにつき1つの条件しか使用できず、標準で複数条件を実現しようとすると、バトルイベントとスイッチを組み合わせるなど工夫しなければなりません。

この行動パターンの条件設定は初期の頃のRPGツクールから驚くほど進化しておらず、むしろ劣化しているとも思えるほどです。条件のラジオボタンがチェックボックスにさえなってくれれば……!と思っていた人は多いのではないでしょうか。

行動パターンの設定項目にはメモ欄もなく、プラグインで制御するのも非常に難しいのですが、今回やりやすい設定方法を思いついたのでプラグイン化しました。

事前準備

まずは「データベース」の「スキル」で、ダミーのスキルを1つ追加します。

名前は何でもいいですが「↓条件追加」などとしておくと分かりやすいかと思います。

ダミーなのでスキルの設定内容は何もいりません。

そしてこのスキルを、プラグインパラメータの「追加条件用スキル」に指定します。

以上で準備は完了です。

複数条件の設定方法

このプラグインの機能としては、この「追加条件用スキル」がスキルとして設定された行動パターンの条件を、直後の行動パターンの条件に追加する、というものです。

例えば以下のような行動パターンが設定されている場合、

スキル 条件
↓条件追加 パーティーLV>=25
ブリザード ターン 3+4*X

パーティーの平均レベルが25以上で、かつターン数が3+4*X(3,7,11…ターン目)の時にブリザードが発動します。

追加条件は2個以上重ねることもでき、例えば以下のような場合は、

スキル 条件
↓条件追加 パーティーLV>=30
↓条件追加 HP 0%~50%
リカバー ターン 1+4*X

パーティーの平均レベルが30以上で、かつ自分のHPが0~50%の範囲内で、かつターン数が1+4*X(1,4,9…ターン目)の時にリカバーが発動します。

追加条件はAND条件として追加され、全ての条件を満たした場合のみ発動可能になります。OR条件は指定できないので、OR条件にしたい場合はその分だけ行動パターンを作成してやる必要があります。

なおレーティングについては、追加条件でない行動パターンのレーティングが採用され、追加条件のレーティングは無視されます。

複数条件が簡単に設定できることで、より敵キャラの行動パターンを細かく制御できるようになりますが、追加条件は矛盾や漏れがないように気を付けないと、発動し得ない行動になったり、どの条件も当てはまらなくて有効な行動がなくなったりといった事態も起こりますので、ご注意ください。

またそもそもの問題として、標準で設定可能な条件の種類が少なく、これは本プラグインでも解消するものではないので、そこはバトルイベントや他プラグインと併用していくことになるかと思います。

プラグインの実装と注意点

プラグインの実装としては、敵キャラのデータ(Enemies.json)を読み込んだ際に、行動パターンの配列を変更して条件設定を配列に変換し、戦闘行動の条件判定の際は全ての条件を満たしているか判定しているだけです。

敵キャラの行動パターンを制御しているプラグインとは競合や意図通りに動作しない可能性があるので、ご注意ください。

拙作プラグイン「複数回行動条件設定プラグイン(PANDA_MultiAction.js)」はメモ欄に行動パターンの番号を記述する必要がありますが、これと併用した場合、この行動パターン番号は条件追加の行動パターンを無視してカウントする点にご注意ください。

複数回行動条件設定プラグインも、これと同じようにダミーのスキルを作って、これより下の行動は2回目の行動でのみ発動、みたいに設定できた方が楽かもしれませんね。気が向いたらそのうちやります。

質問やアドバイスなどはコメント欄まで、お気軽にお願いします。素材利用条件などについては、このサイトについての「提供素材について」の項目などをご覧ください。

[ テクニック ] [ 素材 ] [ プラグイン/スクリプト ] 数値入力ウィンドウを強化

2022-01-30 22:54:58

イベントコマンド「数値入力の処理」のウィンドウを機能強化して、キャンセルボタンを有効にしたり、数値入力の前後に文字列を追加したり、入力可能な数値の最小値・最大値を指定できるプラグインを作成しました。

RPGツクールMZ専用です。ウィンドウ系は仕様が異なるため、MVでは使えませんのでご注意ください。

※ 2022-03-30追記:
オプションでタッチUIをOFFにした場合エラーが発生するバグを修正しました。お手数ですが、Version.1.0.1にアップデートをお願いします。

標準のイベントコマンド「数値入力の処理」では、入力した数値を受け取る変数と数値の桁数を指定するだけですが、このプラグインを導入すると、追加で以下のことができるようになります。

  • キャンセルボタンで数値入力をキャンセル
  • 数値入力の前後に文字列を追加
  • 入力可能な数値の最小値・最大値を設定

標準の「数値入力の処理」ではキャンセルが効かず、数値が0だったらキャンセルと見なすといった処理にすることが多いですが、それだと支障のあるケースもあると思います。

「キャンセル有効」をONにすると、ESCキーやキャンセルボタンで数値入力をキャンセルすることができるようになります。キャンセルした際に変数に格納する数値を指定できるので、-1など通常では入力できない数値を設定しておいて、変数の値が-1かどうかで分岐することができます。

また、数値入力の前後に文字列を追加することができます。入力値の説明や単位などを追記して、分かりやすくすることができます。文字列には各種制御文字も使用可能です。

さらに、入力可能な数値の最小値・最大値を指定できます。最小値・最大値はそれぞれ、直接数値で指定することも、変数で指定することも可能です。

最小値・最大値を可変にしたい場合は、最小値・最大値を変数に格納して、その変数を指定するといった方法になるかと思います。

なお、最小値・最大値の指定処理はトリアコンタンさんのプラグインを参考にさせていただいております。ありがとうございます。

具体的な使い方としては、プラグインコマンド「数値入力ウィンドウ設定」でこれらの設定をすると、次の「数値入力の処理」の際に適用されます。

一度「数値入力の処理」が行われると、これらの設定はリセットされるので、「数値入力の処理」の直前でプラグインコマンドを呼び出すようにするといいでしょう。

ただしRPGツクールの仕様上、「文章の表示」と「数値入力の処理」の間に別の処理を挟むと、数値入力の前にメッセージウィンドウが閉じてしまうため、本当の直前ではなく「文章の表示」よりも前に呼び出す必要があることに、ご注意ください。

具体的な活用方法ですが、私は銀行システムを作る際に活用しています。

銀行に入出金できるのは1000G単位にしたかったため、後ろに文字列で「000G」と追加しています。

また、入力可能な数値の最大値を設定して、所持金以上に預け入れたり、預金額以上に引き出したりできないようにしています。

質問やアドバイスなどはコメント欄まで、お気軽にお願いします。素材利用条件などについては、このサイトについての「提供素材について」の項目などをご覧ください。

[ テクニック ] [ 素材 ] [ プラグイン/スクリプト ] [ ツクール情報 ] 敵の蘇生対象がランダムにならない不具合修正

2022-01-19 01:47:24

敵が蘇生スキルを使ってくる際に、死亡者が複数いたとしても、ランダムではなく必ず先頭の死亡者が対象になってしまうという、RPGツクールMZのコアスクリプトの不具合を修正します。

RPGツクールMVにも同様の不具合があるのですが、ターゲット選択部分のコアスクリプトの構造が微妙に異なるため、今回はMZ専用プラグインとなります。MVへの移植も容易なのですが、検証作業がめんd

以前にも「正しい蘇生術」で、RPGツクールVXに同様のプリセットスクリプトの不具合があることを解明し、修正スクリプトも公開していました。

当時の不具合は、Game_BattleActionのdecide_random_targetメソッドにおいて、対象が味方単体(for_friend?)ならば(生存中の)味方からターゲットをランダムに決定、対象が戦闘不能の味方単体(for_dead_friend?)ならば戦闘不能の味方からランダムに決定、としているつもりが、for_friend?にはfor_dead_friend?の場合も含まれるので、この判定順序では対象を戦闘不能の味方にしていても通常の味方単体で選ばれてしまう、というものでした。

実はMZが出た時に、この不具合がどうなっているのか、コアスクリプトを調べてみたことがあります。

対応するGame_ActionのdecideRandomTargetメソッドを見ると、ちゃんと戦闘不能の味方(isForDeadFriend)を先に判別しており、さすがに不具合は解消されているものだと思っていました。

ところが最近になって、蘇生魔法を使用する敵を作って戦闘テストをしていたところ、何度試しても先頭の死亡者ばかり蘇生してきます。

そこで改めてコアスクリプトを検証してみたところ、Game_ActionのdecideRandomTargetは敵の通常行動時に呼ばれるものではなく、敵がターゲットを決めるメソッドはmakeTargetsであることが判明しました。そしてここから呼ばれているtargetsForDeadを見ると、敵が蘇生スキルを使用するという前提がないせいか、先頭の死亡者が選ばれるような構造になっていました。

本プラグインはそれを修正して、敵が蘇生スキルを使ってくる際に対象者をランダムに選ぶようにしたものです。

質問やアドバイスなどはコメント欄まで、お気軽にお願いします。素材利用条件などについては、このサイトについての「提供素材について」の項目などをご覧ください。