ステートとパラメータに関する質問

こんにちは、ステートとそのパラメータ(および関連する事項)についていくつか質問があります。

  1. ステートAが適用されている状態で、ステートBが適用されますが、Bに「ステート耐性: A」の特性がある場合、ステートAはバトラーに残るのでしょうか?
  2. 「制限による解除」の適用範囲が完全に把握できていません。私の理解では、異なる制限を持つステートが適用されると、そのオプションがチェックされているステートが解除されるのでしょうか?これはすべてのステートに適用されるのでしょうか?
  3. 特定のアクションによってステートのターン継続時間を減少させることは可能ですか?例えば、火傷ステートが水属性の攻撃を受けた際に、ターン継続時間が1(またはすべて!)減少するような場合です。
  4. その点に関連して、ステートの効果がターン継続時間に応じて強くなるようにすることは可能ですか?例えば、残りターン数Xに対して5% + X%のHPダメージを与える毒のような効果です。

1について、State Aは剥がれます。State Resistは新しい状態の付与をブロックするだけでなく、更新時に抵抗中の状態をすべて消去するため、Bを付与するとAは即座に剥がれます。これは、新しい付与は停止するが、すでに付与されている状態はそのままにするState Rate 0%との違いです。

2について、私の理解では、これは戦闘者が自由行動から拘束状態になった際に発動し、その瞬間に「Restrictionで解除」にチェックが入っているすべての状態が剥がれます(1つだけではありません)。ここで混乱しやすいのは、付与される予定の状態もカウントされるため、自身にRestrictionを持ち、かつそのチェックボックスがオンになっている状態は、着いた瞬間に自分自身を解除してしまう点です。

3について、Burnを完全に消し去りたい場合は、水属性のスキルに「状態解除 → Burn」という効果をつけるだけです。ターンを1つ減らす機能はデータベースでは公開されていません。カウントは戦闘者の_stateTurnsに状態IDをキーとして保存されているため、ダメージ計算式でアクセスして1減らすことができます。Burnが状態5の場合、以下のようになります。

b.isStateAffected(5) ? (b._stateTurns[5] = Math.max(b._stateTurns[5] - 1, 0), a.mat * 2 - b.mdf) : a.mat * 2 - b.mdf

状態は0になった瞬間に消えるわけではなく、通常の自動解除タイミングで消去されます。この計算式はヒットごとに評価されるため、反復回数が3の場合、1ターンではなく3ターン消費されてしまう可能性があります。これに依存した構成にする前に、慎重にテストすることをお勧めします。

4について、スリップダメージはHP再生の特性から発生しますが、これは固定の割合であり、残りターン数を取得するフックはありません。VisuStellaのSkills and States Coreには、ダメージを計算式で記述できる<JS HP Slip Damage>という注釈タグが追加されており、ここに「5% + X%」という計算式(Xは残りターン数から取得)を記述することになります。

本当に?この設定がこれほどニッチなものだとは知りませんでした。正直、これまであまり気にしたことがありませんでした。

つまり、上記のような計算式は、単一対象・単一ヒットのスキルに対してのみ実用的だということですか?

なるほど。ただし、VS Skills and States はそれ以外にも多くの機能を追加するので、現時点で導入するかは微妙ですね。もしプラグインが追加するその他の機能 alongside でステートのスケーリングを本当にやりたいなら、後で検討するかもしれません。

これにはフルスイートは不要です。ターンごとの毒ダメージは単一の関数 Game_Battler.prototype.regenerateHp に収まっているため、その機能だけを行うプラグインは約15行で済みます:

(() => {
    const POISON_ID = 6;
    Game_Battler.prototype.regenerateHp = function() {
        let rate = this.hrg;
        if (this.isStateAffected(POISON_ID)) {
            const turns = this._stateTurns[POISON_ID] || 0;
            rate -= 0.01 * turns;
        }
        const value = Math.max(Math.floor(this.mhp * rate), -this.maxSlipDamage());
        if (value !== 0) {
            this.gainHp(value);
        }
    };
})();

これは意図的に関数をエイリアス(別名付け)するのではなく、上書きしています。gainHp_result.hpDamage に書き込むため、元の関数を呼び出した後に追加ダメージ用の gainHp をもう一度呼び出すと、表示されるポップアップには2番目の数値しか表示されなくなります。追加ダメージを maxSlipDamage のクリップ処理内に保つことも重要です。なぜなら、これが「スリップダメージによるノックアウト」がオフの場合でも、スリップダメージでキャラクターが死亡するのを防ぐ仕組みだからです。

タイミングに関する注意点として、onTurnEndupdateStateTurns より先に再生成処理を実行するため、読み取るターンカウントには終了しようとしているターンが含まれたままになります。

私はこれをテストしていないため、これはそのままコピペして使える完成品というよりは、大まかな構成を示したものと捉えてください。

面白いことに、動作確認のためにそのまま試してみたら、予想どおりに機能しました!唯一の違いは、例えば毒のベースが8%の場合、最終的に9%になったことです。ただし、修正済みです。