EternalTDのウェーブと敵
plugins/EternalTD/waves/ 配下のウェーブファイルは、通常のウェーブ、サドンデスのウェーブ、そして任意のプレウェーブまたはウェーブメッセージを含む、レベルの敵編成全体を定義します。各レベル設定は wavesConfigFile: を通じて1つのウェーブファイルを参照します。
トップレベルフィールド
| フィールド | 型 | デフォルト | 注記 |
|---|---|---|---|
isEnabled | bool | true | 無効なウェーブファイルは読み込まれません。その設定に依存するレベルは開始できません |
baseMobAmount | int | 20 | エントリで amount= が指定されていない場合のデフォルト数 |
waveEntities | string list | 必須 | ウェーブごとの敵エントリ |
suddenDeathWaveEntities | string list | 任意 | 設定されたウェーブが尽きた後にサイクル実行される任意のウェーブプール |
prewaveMessages | list of maps | 任意 | 現在のカウンタをキーにするメッセージ。入場時は0、ウェーブN終了後はN |
waveMessages | list of maps | 任意 | ウェーブ開始時に表示されるメッセージ |
サドンデスのエントリがない場合、次のウェーブへの移行時に設定済みの次ウェーブが見つからなければセッションが終了します。通常は最後の建設時間が終わった後ですが、プレイヤーが早めに進めることもできます。
ウェーブエンティティエントリの形式
waveEntities(または suddenDeathWaveEntities)の各行は、コロン区切りのエントリです:
- wave=1:entityType=ZOMBIE:healthMultiplier=1.0:amount=10
- wave=2:entityType=SKELETON:fast:treasure
- wave=5:entityType=WITHER_SKELETON:boss
- wave=8:entityType=PHANTOM:air:horde
| キー | 型 | 注記 |
|---|---|---|
wave | int | 必須。このエントリが属するウェーブ番号 |
entityType | enum | 必須。Bukkit EntityType の正確な列挙値。スポーン可能な生物エンティティを選びます |
healthMultiplier | double | 任意。デフォルトは 1.0。エンティティの最大HPに乗算 |
amount | int | 任意。このエントリに対して baseMobAmount を上書き |
name | string | 任意。カスタム名文字列。解析されて保存されますが、現在のプラグインはスポーンしたモブにこれを適用しません(ネームプレートは代わりにHP/アーマーバーになります) |
resist | フラグ | エンティティをスロー無効としてマーク |
fast | フラグ | 移動速度を上昇 |
treasure | フラグ | キル時のゴールドバウンティを2倍 |
boss | フラグ | 下記のボス数の規則とHP調整を使い、各ボスにボスバーを表示 |
horde | フラグ | amount を2倍にしてHPを半分にする |
air | フラグ | エンティティが経路の4ブロック上にスポーンし、地上の壁を無視 |
キーやフラグの前後に空白を入れず、エンティティ型は大文字、ウェーブ番号・数・HP倍率は正の値にしてください。パーサは空白を除去せず、すべての不正な範囲を拒否するわけではありません。未知のキーは無視されます。通常エントリの書式が不正だとウェーブ設定が無効になります。サドンデスの不正なエントリは警告を出し、それ以前に読み込めたエントリがプールに残る場合があります。解析の成功だけでは、エンティティがスポーンできるとは限りません。
内部の数量計算
amountにはwave / 10が加算され、その後整数に切り捨てられます。そのためamount=20のエントリはウェーブ15で21体、ウェーブ20で22体になります。bossエントリはamountをmax(1, floor(wave / 10))に上書きします。hordeエントリは最終的なamountを2倍にします。- エントリごとの数量に加えて、ウェーブランタイムはウェーブの構築時に複製を追加します。ここで参照されるリストは完全に展開されたモブのリストである点に注意してください — 設定パーサはすでにモブ1体につき1つのオブジェクトを生成しているため、
amount=20の1行は1つではなく連続した20個のインデックスを占めます。偶数インデックスi(0, 2, 4, ...)のうち、その展開済みリストの有効なインデックスでありかつウェーブ番号より小さいものそれぞれについて、インデックスiのモブのクローンが1体追加されます。ボスエントリがこの方法でクローンされることはありません。したがってボーナスモブの数はおよそceil(min(waveNumber, listSize) / 2)になります: ウェーブ1で1体、ウェーブ3〜4で2体、ウェーブ9〜10で5体、ウェーブ15〜16で8体、といった具合に、ウェーブ番号がリストの長さを超えるまで増えていきます。
スポーン間隔は min(floor(200 / totalEntities), 20) tickです。通常のスポーンではカウンタがその2倍を超える必要があります。hordeの間隔では、整数で半分にした間隔の2倍を超える必要があります。厳密な「より大きい」比較なので、正確に2倍ではなくカウンタの1 tickが追加されます。hordeの間隔はウェーブリストで最初に残っているモブから選ぶため、通常とhordeを混ぜるとリストの変化に伴って間隔も変わります。各モブはスポーン時にレベルの開始マスをランダムに1つ選びます。
メッセージブロックの形式
prewaveMessages と waveMessages はどちらもマップのリストを受け付けます:
prewaveMessages:
- wave: 0
message:
- "&aWelcome! Build a couple of basic towers along the path."
- wave: 4
message:
- "&6Heads up: a boss is coming next wave."
prewaveMessages[0] は入場時に実行されます。ウェーブN終了後、次のウェーブに向けた建設中に prewaveMessages[N] が実行されます。ウェーブ5の予告にはキー4を使います。waveMessages[N] はウェーブN開始時に実行されます。キーはサドンデス中も表示上のセッションカウンタを使います。同じキーのメッセージを繰り返し登録すると、後のエントリが上書きします。
ウェーブのライフサイクル
セッションは以下の状態を経由します:
STARTING— プレイヤーが初めて/etd startを実行する前。CONSTRUCTION_PHASE— 防衛フェーズ間の10秒間の建設ウィンドウ。DEFENSIVE_PHASE— 敵がスポーンして経路を歩いている状態。ENDING— プレイヤーが退出、敗北、またはレベルのウェーブが尽きた状態。
通常の建設タイマーは10秒です。/etd start やNext Waveツールで早めに進められますが、チュートリアルの条件は満たす必要があります(チュートリアルレベルを参照)。最初の開始フェーズは開始操作を待ちます。チュートリアルでは最後の条件が受理された時点で進む場合があります。
ウェーブ終了時の挙動:
- ウェーブをクリアすると
waveNumber * 10のゴールドが付与されます。 - そのウェーブでライフを1つも失わなかった場合、ウェーブボーナスの半分に相当する「Perfect」ボーナス(
waveNumber * 10 * 0.5)を受け取れます。告知される数値と実際に付与されるゴールドは一致するようになりました。 - 各ウェーブの報酬は1回だけです — 何らかの理由で完了が二重に報告されたウェーブは2回目が無視され、セッションが終了処理に入った後は一切支払われません。
- ウェーブ終了後、次ウェーブの修飾子文字列が空でなければ告知されます。これは最初の設定済み敵の値であり、混成ウェーブの全エントリをまとめたものではありません。
レベルが終了するとき
セッションが進行するのは、次のウェーブ番号が waveEntities のキーとして存在する場合だけです。そのため、ウェーブ番号は1から連続している必要があります。次の番号が存在しない場合:
- ファイルが
suddenDeathWaveEntitiesを定義していれば、実行はサドンデスへ移行します。 - そうでなければ、レベルは直ちに終了し、実行されなかったウェーブはカウントされません。保存されるハイスコアと完了時のタイトルには、プレイヤーが実際にプレイした最後のウェーブが使われます。
サドンデス
suddenDeathWaveEntities が定義されている場合、設定されたウェーブリストを超えてもレベルは継続します。
サドンデスのプールは設定されたウェーブ番号を順に使います。必要になるたびに現在のプールキーより大きい最小の非負キーを選び、なければ最小のキーに戻ります。プールカウンタの初期値は0なので、正のキーがある場合は最初の周回でキー0が飛ばされます。正のキーを使ってください。番号の抜けは許可されますが、キー0は下記のHP計算にも適しません。
表示上のウェーブカウンタは増え続けます。敵のHP、アーマー、移動速度、基本報酬、スプリッタリングの発生条件は選択したエントリの設定値 wave= を使い、表示カウンタに合わせて自動で増加しません。実行時の追加クローンと属性抽選は表示カウンタを使います。たとえばプールの10と20のエントリは、表示ウェーブ100でも10と20の敵スケーリング値を保ちます。次ウェーブの検索は表示番号ごとに通常エントリを先に確認するため、途中の欠番でサドンデスに入った後でも、後の通常キーが使われる場合があります。
ウェーブエンティティの属性
各ウェーブは独自の属性を持ち、ウェーブごとにローテーションします:
- ウェーブ1 → 火
- ウェーブ2 → 風
- ウェーブ3 → 水
- ウェーブ4 → 土
- (以降繰り返し)
通常のウェーブエンティティは、スポーン時に表示上の waveNumber / 100 の確率でウェーブ属性を継承します。表示ウェーブ100以降は必ず成功します。色付きタグが属性を示します。スプリッタリングは別に作られ、この抽選を受けません。
属性ダメージのルールはタワーの DamageTower クラスで処理されます:
- 同属性の攻撃側 vs 同属性のターゲット — 0.5倍ダメージ(耐性)。
- 反対の単一属性(火 vs 水、風 vs 土) — 2倍ダメージ(クリティカル)。
- フュージョン属性は下の表に従います。それ以外の一致しない組み合わせは1倍ダメージです。
- 無属性のタワーは誰に対しても1倍のダメージを与えます。
| タワー属性 | 2倍ダメージの相手 | 0.5倍ダメージの相手 |
|---|---|---|
| マグマ | 風、水 | 土、火、マグマ |
| 爆発 | 土、水 | 風、火、爆発 |
| 嵐 | 火、土 | 風、水、嵐 |
| 汚泥 | 火、風 | 土、水、汚泥 |
フュージョン属性は、Basic Towerに組み合わせ可能な属性を持つサポートタワーが接触したときに形成されます:
| 組み合わせ | 結果のフュージョン |
|---|---|
| 火 + 土 | マグマ |
| 火 + 風 | 爆発 |
| 水 + 風 | 嵐 |
| 水 + 土 | 汚泥 |
衝突のルールは見た目より狭い範囲にしか適用されません:
- 同じタワーに 土 + 風 が付くと、他に何が付いていても必ず無属性に戻ります。
- 火 + 水 が無属性に戻すのは、3つ以上の異なる属性が関わっている場合だけです。Fire系サポート1つとWater系サポート1つだけが接触しているタワーは、そのうちどちらか一方を任意に保持します。コードが「セット内の最初の属性を選ぶ」処理にフォールスルーし、そのセットが順序を持たないためです。
- 無属性のサポートタワー(Spyglass、Gold Mine)は結果に一切影響しません。属性を持つタワーが1つでも付いた時点で、セットから除外されます。
再計算は毎回Basic Tower本来の無属性から始まるため、最後の属性付きサポートを取り除くとタワーは無属性に戻ります。
HP、アーマー、バウンティのスケーリング
WaveEntity はスポーン時に自身の設定ウェーブ番号(スプリッタリングなら親の半分のウェーブ)を使い、以下を順に適用します:
- 基本HPは
0.5から始まり、ウェーブとともに増加します:health = 0.5 + ((wave - 1)^1.2) / 2。 - ボスエンティティはそれに
baseMobAmount × 0.5を乗算します。 - Hordeエンティティはそれを半分にします。
- バウンティはここで計算されます。 値は
ceil(health)であり、healthMultiplierの適用前、かつAirのペナルティの適用前です。treasureエントリはその後これを2倍にします。 maxHealth = health × healthMultiplier。- Airエンティティは
maxHealthをさらに半分にします。 - アーマーはウェーブ10以降にのみ出現し、
maxHealth / 80に設定されます。
ステップ4の順序が重要です。healthMultiplier が 3.0 ならHPは3倍でも基本報酬は変わらず、Airの敵もHPが半分ながら同等の地上敵と同じ基本報酬になります。Gold Mineはとどめの一撃でボーナスを加算し、結果を整数に切り捨てます。小さな報酬では追加ゴールドが出ない場合があります。
移動速度は次のとおりです:
speed = 0.3 × (1 - slow)
× 1.5 × (1 - slow) if fast
× 0.5 if air
+ wave / 1000
末尾の wave / 1000 は敵の設定ウェーブを使い、Airとスローの倍率を適用した後に加算します。この値はモブの移動速度属性に使われます。Mob でないエンティティの代替処理は、移動tickごとに次の目的地へ0.1ブロックずつテレポートします。そのため、この式はすべてのエンティティに共通する「ブロック/tick」の速度ではありません。
スプリッタリング
ウェーブ20以降、非Airの敵は死亡時に追加の小型モブ(「スプリッタリング」)をスポーンさせます。
- 数: キルごとに
floor(wave / 20)。 - 親が
CAVE_SPIDERの場合、スプリッタリングはSILVERFISHになります。それ以外の場合はCAVE_SPIDERになります。 - スプリッタリングは
floor(parentWave / 2)を使い、経路上の現在位置を継承します。コンストラクタのHP倍率0.5を使い、親のフラグや属性は継承しません。設定ウェーブが十分高い場合、死亡時にさらにスプリッタリングを生むことがあります。 - スプリッタリングは死亡時に0ゴールドしか与えず、Air の敵はスプリッタリングをスポーンさせません。
チュートリアルレベルの特殊ケース
tutorial.yml レベルはマップ座標に結び付いた固定スクリプトを使います:
- 指定された種類のタワーを強調表示されたマスに置く必要があります。同じタワーが既にあれば、その場でアップグレードします。指定マスにある間違ったタワーは売却できます。そのスクリプト段階の間、無関係な設置・売却・アップグレードは拒否されます。最後の条件が受理されると、直ちに次のウェーブを要求します。
- 色付きコンクリートが指定マスを示します。FMMと
reddownarrowモデルが利用可能なら、各マスの上の赤い矢印が必要なタワーやアップグレードを示します。 - ウェーブ1・2・3が終わって建設に入ると
+100ゴールド、ウェーブ4の後には+200を追加します。追加収入であり、必ず購入できる保証ではありません。他のウェーブ番号には追加されません。 - 必要なタワーの各マスは、要求されるタワーごとに色分けされます。Basic Towerは緑のコンクリート、Barricadeは茶色、Sugarは白、Spyglassはシアン、Beam Generatorは黄色、Explosion Factoryは赤、Ice Boxは青、Armor Crusherは灰色、Gold Mineはオレンジ、Obsidian Quarryは紫、それ以外は黒です。
- 各スクリプト段階では、緑のボスバーが設置済みの必要タワー数を
Build towers! done/total!の形式で数えます。2分ごとに、/etd quitで離脱できることをチュートリアルが知らせ、条件が残っている間は現在のウェーブ前メッセージを繰り返します。
プレイヤーのライフとゴールド
- 初期ライフ: 20。
- 初期ゴールド: 150。
- ボスモブが終端に到達するとライフを5消費します。その他すべてのモブはライフを1消費します。
/etd cheatはオフにする場合も含め、切り替えるたびにゴールドを10,000,000、ライフを1,000,000にリセットします。そのセッションは以後ハイスコア対象外のままです。/etd setwave <n>はセッションカウンタと報酬ガードを変更し、チート済みとして記録します。活動中の敵を置き換えたり、そのウェーブを直ちに開始したりはしません。次の移行はn + 1を使います。
ハイスコアの追跡
各レベル設定は highscoreWave と highscorePlayerName を永続化します。非チートセッションの終了時、プラグインは新しいウェーブ番号をレベルファイルに保存し、前のスコアを更新した場合はサーバー全体のメッセージをブロードキャストします。