オーバーワールドでの戦闘攻撃?

1, 2, 6。これらはすべて連動しているため、BASE値を保存・復元するのではなく、毎フレーム別々の要素からプレイヤーのステータスを再構築したらどうでしょうか?各ブーストには独立したパーセント変数があり、無効化時は100になります。値を「戻す」必要がないため、2つのブーストが互いに相殺されることはなく、フォーム変化は即座に反映されます。

追加する変数は「フォーム攻撃力」「フォーム防御力」「アクション攻撃力%」「アクション防御力%」「アイテム攻撃力%」「アイテム防御力%」「アイテムタイマー」です。4つの%変数は100から開始する必要があるので、ゲーム開始時に実行される処理で初期化してください。そうしないと、すべてが0倍になってしまいます。その後、常時実行される並列共通イベントを1つ設定します:

◆条件分岐: VITAL SHAPE = 1
  ◆変数操作: #0XXX フォーム攻撃力 = 20
  ◆変数操作: #0XXX フォーム防御力 = 20
◆条件分岐終了
◆条件分岐: VITAL SHAPE = 2
  ◆変数操作: #0XXX フォーム攻撃力 = 25
  ◆変数操作: #0XXX フォーム防御力 = 15
◆条件分岐終了
(各フォームごとに分岐を作成し、実際の数値を入力してください)
◆条件分岐: アイテムタイマー > 0
  ◆変数操作: #0XXX アイテムタイマー -= 1
  ◆条件分岐: アイテムタイマー = 0
    ◆変数操作: #0XXX アイテム攻撃力% = 100
    ◆変数操作: #0XXX アイテム防御力% = 100
  ◆条件分岐終了
◆条件分岐終了
◆変数操作: #0226 プレイヤー攻撃力 = フォーム攻撃力
◆変数操作: #0226 プレイヤー攻撃力 *= アクション攻撃力%
◆変数操作: #0226 プレイヤー攻撃力 /= 100
◆変数操作: #0226 プレイヤー攻撃力 *= アイテム攻撃力%
◆変数操作: #0226 プレイヤー攻撃力 /= 100
◆変数操作: #0227 プレイヤー防御力 = フォーム防御力
◆変数操作: #0227 プレイヤー防御力 *= アクション防御力%
◆変数操作: #0227 プレイヤー防御力 /= 100
◆変数操作: #0227 プレイヤー防御力 *= アイテム防御力%
◆変数操作: #0227 プレイヤー防御力 /= 100

2について、並列イベントのアイデアは近かったですね。ブーストが乗算されるため、オフにするためのスイッチは不要です。

フォーム7のAについて、BASE、ATK、DEFに触れる6行は以下の2行に置き換えます。35%減らすということは、65を掛けることです:

◆変数操作: #0XXX アクション攻撃力% = 150
◆変数操作: #0XXX アクション防御力% = 65

そして、ActionTimerが0になると、2つのBASE行は以下のようになります:

◆変数操作: #0XXX アクション攻撃力% = 100
◆変数操作: #0XXX アクション防御力% = 100

6について、アイテムにはデータベース内で共通イベントを設定し、アイテムの「効果」から呼び出します。共通イベントでは、アイテム攻撃力% = 150、アイテムタイマー = 600(10秒間)を設定します。フォームブーストとアイテムブーストはそれぞれ独立した%変数を持つため、片方が終了してももう片方には影響しません。プレイヤー攻撃力やプレイヤー防御力を直接設定する他の処理がある場合は、これを削除する必要があります。そうしないと競合します。

  1. 良さそうです!

  2. チェックは「≥ 2」となっていますが、おそらく「≥ 6」の意図だと思われます。群れ発生は、おそらく+= 1が非常に末尾にあるためです。ループ内で待機しているスポナーはすべて、カウントが同時に減少する瞬間を目撃し、すべてが通過し、ランダム待機が完了するまで自分自身のカウントにはなりません。+= 1をElseブロックのトップ、チェックの直下に移動したらどうでしょうか。そうすれば、条件を満たした瞬間にその位置が占有されます。その後、ENEMY AMOUNT SPAWNEDのロールでまだスポーンしない場合もあるため、その分岐では位置を解放する必要があります:

◆変数操作: #0188 敵に勝利 += 1
◆変数操作: #0184 画面上の敵数(RN?) -= 1
◆イベント処理を終了

GO ONWARD THREEにある+= 1は削除します。

  1. TurnInPlaceを使用しているとのことなので、まずプラグインパラメータを確認してください。すでにこれ用のスイッチがあるかもしれません。もしない場合、小さなプラグインを作成するのが最もクリーンな方法だと思われます。イベントでは、矢印キーによる移動を止めることなくターンを止めることはできないためです。10を希望するスイッチに置き換えてください:
/*:
 * @target MZ
 * @plugindesc スイッチがONの間のみターンする。
 */
(() => {
    const _executeMove = Game_Player.prototype.executeMove;
    Game_Player.prototype.executeMove = function(direction) {
        if ($gameSwitches.value(10)) {
            this.setDirection(direction);
        } else {
            _executeMove.call(this, direction);
        }
    };
})();

その後、トグルはボタンを監視する並列共通イベントとして機能します。スイッチがONならOFFに、OFFならONに切り替えます。

1/2 - ここは戦闘開始時に変数を設定するイベントの一部です。

◆制御変数:#0228 プレイヤーHP = 200
◆制御変数:#0226 プレイヤー攻撃力 = 75
◆制御変数:#0227 プレイヤー防御力 = 50
◆制御変数:#0252 行動攻撃力率 = 100
◆制御変数:#0253 行動防御力率 = 100
◆制御変数:#0254 アイテム攻撃力率 = 100
◆制御変数:#0255 アイテム防御力率 = 100

あなたは提示してくれた内容を使って、STATS HANDLER(ステータスハンドラー)という共通イベントを無限に実行する新しい並列処理イベントを作成しました。

私がミスしていないことを確認するため、そのイベントの下部にあるすべての変数を以下に示します。

◆制御変数:#0226 プレイヤー攻撃力 = 形態攻撃力
◆制御変数:#0226 プレイヤー攻撃力 *= 行動攻撃力率
◆制御変数:#0226 プレイヤー攻撃力 /= 100
◆制御変数:#0226 プレイヤー攻撃力 *= アイテム攻撃力率
◆制御変数:#0226 プレイヤー攻撃力 /= 100
◆制御変数:#0227 プレイヤー防御力 = 形態防御力
◆制御変数:#0227 プレイヤー防御力 *= 行動防御力率
◆制御変数:#0227 プレイヤー防御力 /= 100
◆制御変数:#0227 プレイヤー防御力 *= アイテム防御力率
◆制御変数:#0227 プレイヤー防御力 /= 100

フォーム7のステータスが、プレイヤーの攻撃力と防御力から、行動の攻撃力率と防御力率に変更されたことに気づきました。攻撃ハンドラー内のプレイヤー攻撃力と防御力のすべてのインスタンスを「行動」に変更する必要がありますか?それともこれだけでしょうか?また、新しい共通イベントは、プレイヤーの攻撃力を高め、防御力を下げるために、行動の攻撃力/防御力率を変換する役割を果たしているのでしょうか?

6- 各アイテムに共通イベントを割り当てる必要がありますか?私のアイデアでは、「祭壇」というアイテムがあり、プレイヤーが自分のバッグからアイテムを祭壇に置く(現時点では回復、攻撃力強化、防御力強化のいくつかの種類のアイテムがあります)、30秒待つ、そしてAボタンを押すことで祭壇からアイテムを回収できるようになり、プレイヤーは10秒間攻撃力が2倍になる、あるいは5秒間防御力が3倍になるなどの効果を得る、というものです。

4- これを「取るべきアクションのリスト」の形式に整理してもらえますか?私には理解するには範囲が広すぎます。申し訳ありませんが、敵の画面上の数をチェックする箇所を >_ 6 に変更しました。

5- TurnInPlace にはそのようなパラメータがないため、確認しました。そのミニプラグインを追加しました。では、トグル(切り替え)は並列処理イベントで以下のようなものになりますか?

もし input (CTRL) がトリガーされ、かつ InBattle がオンの場合、共通イベント Arrow Toggle を呼び出す?
そして Arrow Toggle という共通イベントの中では、Toggle Arrows (188) をオンにする?

正直なところ、同じボタンで2つの異なるアクションを実行する方法がわかりません。

1 と 2. 底辺の行は正しく見えます。ただし、戦闘開始時の処理で2点ほど指摘があります。STATS_HANDLER が毎フレーム Player ATK と Player DEF を書き換えるようになったため、そこに記述されている 75 や 50 は直ちに上書きされてしまいます。これらの数値は、ハンドラー内の Form ATK と Form DEF の行に移動してください。現時点ですべてのフォームの初期値が ATK 75、DEF 50 であるなら、各ブランチでそれらの値を使用するだけで大丈夫です。また、4つの % 行の隣に Item Timer = 0 を追加することをお勧めします。

プレイヤーのステータスを変更する箇所のみが % 変数として機能します。例えば、フォーム7のAボタンでそれらを 150 と 65 に設定し、後に 100 に戻すような場合です。Player ATK や Player DEF を読み取る箇所(ダメージ計算式など)はそのまま変更の必要はありません。はい、まさにその通りがハンドラーの動作です。毎フレーム、フォームの数値から始めて、Action % と Item % を乗算していきます。Player ATK BASE や Player DEF BASE は不要になりました。

  1. いいえ、祭壇自体がそれらを設定できますし、アイテムごとに共通イベントを用意する必要はありません。以下のような構成にします。Altar Item、Altar Timer、Altar State は新しい変数です。祭壇はアクションボタンイベントとして実装します:
◆If: Altar State = 0
  ◆Select Item: Altar Item, Regular Item
  ◆If: Altar Item > 0
    ◆Script: $gameParty.loseItem($dataItems[$gameVariables.value(XXX)], 1);
    ◆Control Variables: #0XXX Altar Timer = 1800
    ◆Control Variables: #0XXX Altar State = 1
  ◆End
: Else
  ◆If: Altar Timer = 0
    ◆If: Altar Item = (あなたのx2 ATKアイテムのID)
      ◆Control Variables: #0254 Item ATK % = 200
      ◆Control Variables: #0XXX Item Timer = 600
    ◆End
    ◆If: Altar Item = (あなたのx3 DEFアイテムのID)
      ◆Control Variables: #0255 Item DEF % = 300
      ◆Control Variables: #0XXX Item Timer = 300
    ◆End
    ◆If: Altar Item = (回復アイテムのID)
      ◆Control Variables: #0228 Player HP += 50
    ◆End
    ◆Control Variables: #0XXX Altar State = 0
  ◆End
◆End

スクリプト行の XXX は Altar Item の変数番号です。1800 は 30秒を意味します。その後、STATS_HANDLER 内で Item Timer ブロックの隣に以下を追加します:

◆If: Altar Timer > 0
  ◆Control Variables: #0XXX Altar Timer -= 1
◆End

もし A がイベントと会話するボタンとは別のボタンである場合は、お知らせください。変更します。

  1. もちろんです。スポーンイベント内で設定します。
  2. 「If: 画面内の敵数 RN? ≥ 6」の Else ブランチを探します。
  3. その Else ブランチ内の最上部、つまり「待ち時間はどのくらい?」という行の上に、以下を追加します:Control Variables: #0184 Enemies Onscreen RN? += 1。
  4. 「ENEMIES WON AGAINST += 1」を含む Else ブランチを探します。その行と「Exit Event Processing」の間に、Control Variables: #0184 Enemies Onscreen RN? -= 1 を追加します。
  5. ラベル「GO ONWARD THREE」の下にある Enemies Onscreen RN? += 1 を削除します。
  6. はい、近いです。まず、プラグイン内の 10 を 188 に変更し、Toggle Arrows スイッチを監視するようにします。その後、並列イベントは以下のように動作します:
◆If: Script: Input.isTriggered("control")
  ◆If: InBattle is ON
    ◆Common Event: Arrow Toggle
  ◆End
◆End

同じボタンで2つの動作を行う場合、Arrow Toggle 内に現在のスイッチの状態を確認する If 文を追加するだけです:

◆If: Toggle Arrows is ON
  ◆Control Switches: #0188 Toggle Arrows = OFF
: Else
  ◆Control Switches: #0188 Toggle Arrows = ON
◆End

Ctrl について一つ注意点があります:以前発見した通り、テストプレイ中に Ctrl を押し続けると壁をすり抜けられます。実際のゲームには影響しませんが、トグルのテスト時に混乱を招く可能性があります。

1/2-わかりました。戦闘開始時のATKとDEFの行を削除し、アイテムタイマーを0に設定しました。

Form 7と同じステータス置換をForm 1と2にも行うべきでしょうか?Form 1と2も、Aアクションで自身のATKとDEFを強化しています。これらは自身のステータスを強化する唯一のものです。

4-これは実際に機能しているようです!最初はステータスを間違えて設定したため少し不安でしたが、大丈夫そうです!

5-動作していません。すべての部分を記載します。
(なお、CTRLキーを押した後に影響がある場合を除き、問題ありません。通常のゲームプレイでは、この目的にはアクセスしやすく便利なボタンですので、これで対応します。)

(ちなみに、10を188に変更しました。)

6-正直に言うと、あなたが作成した「アイテム選択」の機能をどのように実装すればよいかがわかりません。lol、変数とアイテムタイプしか表示されません。

1と2. はい、フォーム7と同じです。フォーム1と2のAアクションのうち、プレイヤーの攻撃力(ATK)や防御力(DEF)を設定する行は、攻撃力%や防御力%として扱われます。計算方法は以前と同じで、30%アップは130、20%ダウンは80となります。タイマーが切れると、これらは100に戻ります。

  1. 動作してよかったです!

  2. 両方のイベントは正しく設定されているようですので、「TurnInPlace」がミニプラグインがフックする部分を通らずにプレイヤーを移動している可能性があります。このバージョンではステップ自体を捉えるようになっているため、「TurnInPlace」がどのようにしてそこに到達するかは関係ありません。これを古いバージョンと入れ替え、プラグインリストの最も下に配置してください。そうすれば、「TurnInPlace」に対して最終的な決定権を持つことができます:

/*:
 * @target MZ
 * @plugindesc スイッチがONの間のみ回転します。
 */
(() => {
    const _moveStraight = Game_Player.prototype.moveStraight;
    Game_Player.prototype.moveStraight = function(d) {
        if ($gameSwitches.value(188) && !this.isMoveRouteForcing()) {
            this.setDirection(d);
        } else {
            _moveStraight.call(this, d);
        }
    };
})();

isMoveRouteForcing の部分は、RECOILや他のプレイヤーへの「移動経路の設定」が、トグルがONの間でもプレイヤーを移動できるようにします。

それでも歩いている場合は、テストプレイ中にF9を押して、Ctrlを押したときにスイッチ188が実際にONになるかどうかを確認してください。もしONにならない場合は、問題はイベント側にあります。その並列イベントがどこにあるか、そしてその時点で「Battle STARTED」がONになっているかどうかを教えていただけますか?

  1. これらの2つのフィールドがあれば十分です。変数を「祭壇アイテム」に設定し、アイテムタイプを「通常アイテム」に設定してください(または、祭壇アイテムがどのタイプかによって適宜設定してください)。プレイヤーが何かを選んだ場合、そのIDが「祭壇アイテム」に格納されます。キャンセルした場合は0になります。これより下の「If: 祭壇アイテム > 0」の条件は、この値をチェックしています。

1/2-ATK/DEFのベース値を置き換える必要があるのか分からなかったのですが、変更後の状態は以下の通りです。確認のため送信します。

5-今では動作しています!

6-現在これに取り組んでいます。問題があれば更新します。

質問1:Altar Timerは、アイテムを設置してからスポーンするまでの時間を指すのか、それともステータス上昇アイテムの効果が元に戻るまでの時間を指すのでしょうか?

2:プレイヤーのHPを整数ではなく分数で回復させることは可能ですか?
例えば、あるHPアイテムはHPの1/5を回復し、別のアイテムは1/4、さらに別のアイテムは1/3を回復するような感じです。

何かの理由で完全には送信できなかったため、やむを得ず awkward に分割しました。

何かご意見はありますか?

フォーム1と2のAについて、確認すべき箇所はActionTimerが0になる瞬間です。その2行は現在「Action ATK % = 100」と「Action DEF % = 100」であるはずです。もしそれでも「Player ATK = Player ATK BASE」と表示されている場合、%が戻らないため、バフが解除されず、*= によって押すたびに累積されてしまうと考えられます。フォーム1、2、7がすべてこのActionTimerブロックを共有しているなら、リセットは3つすべてに適用されます。

これを導入すれば、BASEに関する行は不要になります(それらを読み込むものがなくなったため)。Aを押した際には%は常に100になるため、「Action ATK % = 150」だけで *= と /= の組み合わせと同じ効果を得られ、フォーム2についても同様に「Action DEF % = 150」となります。

  1. はい、それで正解です。「Altar Timer」はアイテムを祭壇に置いた後の30秒間の待機時間を指し、「Item Timer」は回収後にバフが持続する時間を指します。

  2. はい、単に基準となる最大HPが必要なのです。「Player Max HP」と「Heal」は新しい変数です。戦闘開始時の「Player HP = 200」の隣に「Player Max HP = 200」を設定し、その後各根茎(rhizome)がそこから回復量を計算します:

◆If: Altar Item = 36
  ◆Control Variables: #0XXX Heal = Player Max HP
  ◆Control Variables: #0XXX Heal /= 5
  ◆Control Variables: #0228 Player HP += Heal
◆End

/= 4 は4分の1、/= 3 は3分の1です。五分の二のような場合は、ステータスと同様にまず掛けて最後に割る必要があるため、*= 2 としてから /= 5 にします。これはSTATS HANDLER内にあり、回復量が最大値を超えないようにするためのものです:

◆If: Player HP > Player Max HP
  ◆Control Variables: #0228 Player HP = Player Max HP
◆End
  1. どちらの場所でも構いません。2つのブロックは互いの変数を参照しないため、順序は問題ありません。

  2. いいえ、その1行で全てのアイテムに対応できます。「Select Item」はプレイヤーが選んだアイテムのIDを「Altar Item」に格納し、スクリプトはそのIDを読み取って該当アイテムを1つ減らします。「Change Items」では、ウィンドウ内で事前に選択されたアイテムを指定する必要があるため、これには適しません。変更すべき点は XXX で、まだあなたのデータに残っています。ここには「Altar Item」の変数番号を入れる必要があります。「Altar State」が258、「Altar Timer」が260であるとすると、「Altar Item」は259だと推測されます。そうなると以下のようになります:

$gameParty.loseItem($dataItems[$gameVariables.value(259)], 1);

XXX のままにしておくと、アイテムが祭壇に置かれた瞬間にゲームがエラーで停止してしまいます。

  1. 電球(bulbs)の部分を見るべきでしょう。4つとも42、44、47、46を使用しており、ハディーストツク(Hardy Shoots)と同じIDです。これらはストツクからコピーされた可能性があります。現状では、赤いハディーストツクが自分のブランチを実行した後、直ちに赤い電球の処理が行われるため、電球のDEFが付与されてしまいます。電球の正しいIDを入れることで解決します。根茎の += 20 の行には、2番で述べた Heal の行が入ります。

  2. 押して回収する動作は、すでにあなたのシステムでZキーで行われています。効果が発動するのはElse分岐内であり、これはプレイヤーが祭壇まで歩いてボタンを押したときにのみ実行されるため、30秒経過しても自動的に何も付与されません。Action ButtonイベントはOK(Zキー)でのみ発火します。Aはaction3であり、あなたのフォームのAアクションと同じキーです。もし祭壇でAキーを使用する場合、そこで押すと現在のフォームのAアクションも同時に発火してしまいます。祭壇にはZキーを使いますか? それともどうしてもAキーを使いたいですか?

いずれにせよ、追加すべきなのは準備完了時に音を鳴らすことです。そうすればプレイヤーは戻ってくることを知ることができます。これはあなたのSTATS HANDLER内のAltar Timerブロックにあるクールダウン音と同じトリックです:

◆If: Altar Timer > 0
  ◆Control Variables: #0260 Altar Timer -= 1
  ◆If: Altar Timer = 0
    ◆Play SE: (準備完了用のSE)
  ◆End
◆End

1-ありがとう

2-実装しました、ありがとうございます!

3-ありがとう

4-ああ、なるほど!実装しました。

5-おっと、いい指摘ですね!実装しました。

6-おっと。そうですね、確かに lol。忘れてしまいがちでだらしないミスでした。あと、「A」と言ったときは「Aに相当する入力」を意味します。次からは明確に区別するように気をつけます。

最初は、Zの攻撃(A)がAltarイベントに触れたときに一時的にオフになるのかと思っていましたが、考えてみると、単に触れたら即座にオフにするのが良さそうな気がします。プレイヤーとの接触の場合も同じように機能すると想定してよろしいでしょうか?

おそらくこれでアイテムのメカニクスは完結し、その点については大変感謝しています!次にForm 5の説明を作成しようと思います。

実は、もうかなり進んでいるので、プレイヤーのダメージ計算式を実装するにはちょうどいい時期かもしれません。何か問題があれば報告します。

今、すごく興奮しています!数日前に実装していたプレイヤーのダメージ/敵の攻撃コードを再び導入したところ、基本攻撃がプレイヤーに対して正常に機能しました!本当に感謝しています。とても嬉しいです。

すべての敵がその形態に関係なく基本攻撃を共有することでバランスを保つことに満足しているため、敵が与えられた形態(1から8まで。ただし5は未実装なので除く)に応じてプレイヤーのA攻撃とS攻撃を使用できるようにするには、どのような変更が必要でしょうか?敵の設定コードにはすでにSV: Enemy Moveset変数が存在します。特殊な動きに関連して私が加える唯一の変更点は、それらがプレイヤーに対してノックバックを引き起こさないようにすることです。

また、整理のためにも、これらの動きセットは共通イベントとして配置できるものと理解していますが、それで正しいでしょうか?

祭壇の上では、プレイヤーの接触は同じように機能します。踏むと発動し、正面でZキーを押しても発動します。唯一の違いは、空の状態のときにぶつかると戦闘中であってもアイテムリストが開くことです。

敵の動きについては、敵ページに3つの追加項目と、各フォームごとに1つの共通イベントを追加します。はい、共通イベントです。敵から共通イベントを呼び出すと、その敵として実行されるため、内部の「このイベント」や this.character(0) は、呼び出した敵を指します。これはすでに動作している ENEMY SWING と同じ仕組みです。敵のループは、コマンドがページに含まれている場合と同様に、完了するまで待ちます。自己変数もそれに従うべきだと思いますが、それは EliMZ_SelfVariables がどのイベントを見つけるかによります。そのため、まずフォーム3を実装し、残りを移動させる前に各敵が独自のクールダウンを維持していることを確認するのが良いでしょう。

SV: Max HP(最大HP)、SV: A Cooldown(Aクールダウン)、SV: S Cooldown(Sクールダウン)、SV: Speed Timer(速度タイマー)、SV: Ram Steps(突進ステップ)は新しい自己変数であり、他のものと同じ方法で設定されます。Pick(選択)、Roll(振り出し)、Half HP(半分のHP)、Ram Hit(突進ヒット)は、それらがその場でしか使用されないため通常の変数にできます。

  1. 設定において、設定スイッチをONにする行の直上、つまりすべてのフォームに適用される場所に記述します:
◆Control Variables: #0XXX SV: Max HP = SV: This event HP
  1. SV: Atk Cooldown(攻撃クールダウン)のカウントダウンの隣に配置し、これらが毎パスカウントダウンするようにします:
◆If: SV: A Cooldown > 0
  ◆Control Variables: #0XXX SV: A Cooldown -= 1
◆End
◆If: SV: S Cooldown > 0
  ◆Control Variables: #0XXX SV: S Cooldown -= 1
◆End
◆If: SV: Speed Timer > 0
  ◆Control Variables: #0XXX SV: Speed Timer -= 1
  ◆Script: this.character(0).setMoveSpeed(6);
  ◆If: SV: Speed Timer = 0
    ◆Script: this.character(0).setMoveSpeed(4);
  ◆End
◆End

毎パス速度を設定することで、ノックバック時の速度4がブーストを短く切るのを防げます。

  1. ロール(Roll)は、Basic(基本攻撃)の準備運動が始まる場所に配置します。これは基本攻撃の下にある Else を置き換えます:
: Else
  ◆If: SV: Atk Cooldown = 0
    ◆Control Variables: #0XXX SV: Distance = Math.abs($gamePlayer.x - this.character(0).x) + Math.abs($gamePlayer.y - this.character(0).y)
    ◆If: SV: Distance = 1
      ◆Script: this.character(0).turnTowardPlayer();
      ◆Control Variables: #0XXX Pick = 0
      ◆Control Variables: #0XXX Half HP = SV: Max HP
      ◆Control Variables: #0XXX Half HP /= 2
      ◆If: SV: This event HP < Half HP
        ◆Control Variables: #0XXX Roll = Random 1..6
        ◆If: Roll = 1
          ◆If: SV: A Cooldown = 0
            ◆Control Variables: #0XXX Pick = 1
          ◆End
        ◆End
        ◆If: Roll ≥ 2
          ◆If: Roll ≤ 3
            ◆If: SV: S Cooldown = 0
              ◆Control Variables: #0XXX Pick = 2
            ◆End
          ◆End
        ◆End
      ◆End
      ◆If: Pick = 0
        ◆Set Movement Route: This Event
          : Wait: 5 frames
        ◆Control Variables: #0XXX SV: Windup = 5
      : Else
        ◆If: SV: Enemy Moveset = 3
          ◆Common Event: MOVESET 3
        ◆End
        ◆Control Variables: #0XXX SV: Atk Cooldown = 60
      ◆End
    ◆End
  ◆End
◆End

HPが半分以下の場合、1はA攻撃、2または3はS攻撃を表すため、S攻撃は2倍の頻度で発生します。ロールがまだクールダウン中のスペシャル攻撃に当たった場合、敵は代わりに基本攻撃を行います。Random 1..6 は約半分がスペシャル攻撃になります。6の値を上げるとそれらは希少になり、1..9 にすると約3分の1になります。各フォームの共通イベントには、Moveset = 3 の横に独自の If 文を追加します。フォームに共通イベントがない間は、そのフォームを持つ敵はスペシャル攻撃をロールした場合でもスイングをスキップします。

次に、トリガー:なしの新規共通イベント MOVESET 3 を作成します:

◆If: Pick = 1
  (ブースト音、ある場合)
  ◆Control Variables: #0XXX SV: Speed Timer = 300
  ◆Control Variables: #0XXX SV: A Cooldown = 600
◆End
◆If: Pick = 2
  ◆Control Variables: #0XXX SV: S Cooldown = 300
  ◆Script: this.character(0)._locked = true;
  ◆Set Movement Route: This Event (Skip, Wait)
    : Blend Mode: Screen
    : Wait: 10 frames
    : Speed: 6
  ◆Control Variables: #0XXX SV: Ram Steps = 4
  ◆Loop
    ◆Control Variables: #0XXX Ram Hit = $gamePlayer.pos($gameMap.roundXWithDirection(this.character(0).x, this.character(0).direction()), $gameMap.roundYWithDirection(this.character(0).y, this.character(0).direction())) ? 1 : 0
    ◆If: Ram Hit = 1
      (基本攻撃と同じヒット音またはフラッシュ)
      ◆Control Variables: #0232 SV: Damage = SV: This Event ATK
      ◆Control Variables: #0232 SV: Damage *= 130
      ◆Control Variables: #0233 SV: Def Calc = Player DEF
      ◆Control Variables: #0233 SV: Def Calc += 100
      ◆Control Variables: #0232 SV: Damage /= SV: Def Calc
      ◆Control Variables: #0228 Player HP -= SV: Damage
      ◆Break Loop
    ◆End
    ◆If: SV: Ram Steps = 0
      ◆Break Loop
    ◆End
    ◆Control Variables: #0194 SV: My X = Map X of This Event
    ◆Control Variables: #0195 SV: My Y = Map Y of This Event
    ◆Set Movement Route: This Event (Skip, Wait)
      : 1 Step Forward
    ◆Control Variables: #0XXX SV: Ram Steps -= 1
    ◆Control Variables: #0244 SV: KB X = Map X of This Event
    ◆Control Variables: #0245 SV: KB Y = Map Y of This Event
    ◆If: SV: KB X = SV: My X
      ◆If: SV: KB Y = SV: My Y
        ◆Break Loop
      ◆End
    ◆End
  ◆Repeat Above
  ◆Set Movement Route: This Event (Skip, Wait)
    : Blend Mode: Normal
    : Speed: 4
  ◆Script: this.character(0)._locked = false;
◆End

ブーストの300と600は、あなたのスピードフォームのダッシュに合わせており、突進は4タイル、速度6、威力130を使用しています。各ステップの前に突進は前方のタイルをチェックします。10フレームのフラッシュの後にもあなたがそこにいればヒットし、もしあなたが避けていれば通り過ぎます。壁や他の敵があればそこで停止し、あなたを押し返しません。_locked の行はノックバックループと同じトリックであり、敵自身の移動が間に挟まれるのを防ぎます。

他のフォームも同じパターンに従います。フォーム1、2、7のAは、セットアップ時に保存された基本値を用いて、SV: This Event ATK と DEF を上昇させ、タイマーが切れると元に戻します。Sの爆発攻撃は、攻撃の衝突判定を使うのではなく敵の前方のタイルをチェックし、Enemy Swing のような複製を生成して視認できるようにします。フォーム4は、向いている方向の列全体または行をチェックします。フォーム6のウォーキングとフォーム8のトラップはより複雑なもので、生成された複製が独自にプレイヤーを探知する必要があります。

問題があればお知らせしますし、できる限り入念にテストします。

新しい変数をすべて「自分自身の変数(Self Variables)」にしたのは、他の敵の計算と干渉しないようにするためです。

  1. Max HPのコピー = このイベントHP設定は、各フォームのステータスを設定する変数の直下に配置しています。

  2. 新しい If > ブランチは、SV: Windup > ブランチの直上に配置しました。

  3. 間違いがないか確認するために記述したコードは以下の通りです。

    ◆If:SV: Distance = 1
      ◆Script:this.character(0).turnTowardPlayer();
      ◆Control Variables:#0281 SV: Pick = 0
      ◆Control Variables:#0283 SV: Half HP = SV: Max HP
      ◆Control Variables:#0283 SV: Half HP /= 2
      ◆If:SV: This event HP < SV: Half HP
        ◆Control Variables:#0282 SV: Roll = Random 1..6
        ◆If:SV: Roll = 1
          ◆If:SV: A Cooldown = 0
            ◆Control Variables:#0281 SV: Pick = 1
            ◆
          :End
          ◆
        :End
        ◆If:SV: Roll ≥ 2
          ◆If:SV: Roll ≤ 3
            ◆If:SV: S Cooldown = 0
              ◆Control Variables:#0281 SV: Pick = 2
              ◆
            :End
            ◆
          :End
          ◆
        :End
        ◆
      :End
      ◆If:SV: Pick = 0
        ◆Set Movement Route:This Event
        :Set Movement Route:◇Wait:5 frames
        ◆Control Variables:#0270 SV: Windup = 5
        ◆
      :Else
        ◆If:SV: Enemy moveset = 3
          ◆Common Event:MOVESET 3
          ◆
        :End
        ◆Control Variables:#0269 SV: Atk Cooldown = 60
        ◆
      :End
      ◆
    :End
  1. ミスがないことを確認するために、Form 3の共通イベント全体も以下に示します。
◆If:SV: Pick = 1
  ◆Show Balloon Icon:This Event, User-defined 1
  ◆Play SE:SFX/Fighting/BSFX GO UP (100, 100, 0)
  ◆Control Variables:#0278 SV: Speed Timer = 300
  ◆Control Variables:#0276 SV: A Cooldown = 600
  ◆
:End
◆If:SV: Pick = 2
  ◆Control Variables:#0277 SV: S Cooldown = 300
  ◆Script:this.character(0)._locked = true;
  ◆Set Movement Route:This Event (Skip, Wait)
  :Set Movement Route:◇Blend Mode:Screen
  :Set Movement Route:◇Wait:10 frames
  :Set Movement Route:◇Speed:6
  ◆Control Variables:#0279 SV: Ram Steps = 4
  ◆Loop
    ◆Control Variables:#0284 SV: Ram Hit = $gamePlayer.pos($gameMap.roundXWithDirection(this.character(0).x, this.character(0).direction()), $gameMap.roundYWithDirection(this.character(0).y, this.character(0).direction())) ? 1 : 0
    ◆If:SV: Ram Hit = 1
      ◆Set Movement Route:Player
      :Set Movement Route:◇Blend Mode:Additive
      ◆Common Event:DAMAGE SFX
      ◆Common Event:SCREENSHAKE SMALL
      ◆Control Variables:#0232 SV: Damage = SV: This Event ATK
      ◆Control Variables:#0232 SV: Damage *= 130
      ◆Control Variables:#0233 SV: Def Calc = Player DEF
      ◆Control Variables:#0233 SV: Def Calc += 100
      ◆Control Variables:#0232 SV: Damage /= SV: Def Calc
      ◆Control Variables:#0228 Player HP -= SV: Damage
      ◆Wait:30 frames
      ◆Set Movement Route:Player
      :Set Movement Route:◇Blend Mode:Normal
      ◆Break Loop
      ◆
    :End
    ◆If:SV: Ram Steps = 0
      ◆Break Loop
      ◆
    :End
    ◆Control Variables:#0194 SV: My X = Map X of This Event
    ◆Control Variables:#0195 SV: My Y = Map Y of This Event
    ◆Set Movement Route:This Event (Skip, Wait)
    :Set Movement Route:◇1 Step Forward
    ◆Control Variables:#0279 SV: Ram Steps -= 1
    ◆Control Variables:#0244 SV: KB X = Map X of This Event
    ◆Control Variables:#0245 SV: KB Y = Map Y of This Event
    ◆If:SV: KB X = SV: My X
      ◆If:SV: KB Y = SV: My Y
        ◆Break Loop
        ◆
      :End
      ◆
    :End
    ◆
  :Repeat Above
  ◆Set Movement Route:This Event (Skip, Wait)
  :Set Movement Route:◇Blend Mode:Normal
  :Set Movement Route:◇Speed:4
  ◆Script:this.character(0)._locked = false;
  ◆
:End

機能面では、うまく動いているようです!プレイヤーを突進させ、一時的に速度を上げることができます。(ただし、扱いやすくするために速度を5に弱体化しました。)

小さな追加問題が2つあります。

  1. 敵は攻撃を実行し、プレイヤーを見逃す瞬間に、プレイヤーから背を向けることがかなり頻繁にあります。
  2. 敵が攻撃中の間、プレイヤーはその敵にダメージを与えられないようです。私が確認した限り基本動作かもしれませんが、すべての攻撃でそうなる可能性があります。

重要なのは、AアクションとSアクションを敵自身が使用できるコードに変換することでしょうか?Form 5のAアクションを除くすべてのアクションは、単に変数を変更するだけであることに言及しておきます。また、Form 5のムーブセットはまだ実装されていない点も考慮してください。

本当にありがとうございます。この手のことは、100万年かけても理解できなかったでしょう。