EternalTD 波次与敌人
plugins/EternalTD/waves/ 下的波次文件定义了某关卡的完整敌人阵容,包括普通波次、突袭波次以及可选的波前消息或波次消息。每个关卡配置都通过 wavesConfigFile: 引用一个波次文件。
顶级字段
| 字段 | 类型 | 默认值 | 备注 |
|---|---|---|---|
isEnabled | bool | true | 在此处禁用同样会禁用依赖此文件的关卡 |
baseMobAmount | int | 20 | 当条目未指定 amount= 时使用的默认数量 |
waveEntities | string list | 必填 | 按波次列出的敌人条目 |
suddenDeathWaveEntities | string list | 可选 | 可选的循环波次池,在已配置的波次用尽后运行 |
prewaveMessages | list of maps | 可选 | 在指定波次开始之前显示的消息 |
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。乘以实体的最大生命值 |
amount | int | 可选。覆盖此条目的 baseMobAmount |
name | string | 可选。自定义名称字符串。会被解析并保存,但插件目前不会把它应用到生成的生物上(名牌显示的是生命值/护甲条) |
resist | flag | 将实体标记为免疫减速 |
fast | flag | 提高移动速度 |
treasure | flag | 击杀时的金币赏金翻倍 |
boss | flag | 以单个 Boss 形式生成,带有缩放后的生命值和 Boss 血条 |
horde | flag | amount 翻倍,生命值减半 |
air | flag | 实体在路径上方 4 格处生成,无视地面墙体 |
内部数量计算
amount会加上wave / 10后再截断为整数,因此一个amount=20的条目在第 15 波产出 21 只生物,在第 20 波产出 22 只。boss条目会将amount覆盖为max(1, floor(wave / 10))。horde条目会使最终amount翻倍。- 在每条目数量之上,波次运行时在构建该波次时还会追加副本。请注意,它索引的那个列表是完全展开后的生物列表——配置解析器已经为每只生物各生成了一个对象,因此单独一行
amount=20会贡献 20 个连续索引,而不是一个。对每一个既是该展开列表中的有效索引又小于波次编号的偶数索引i(0, 2, 4, ...),都会额外追加一个索引i处生物的克隆。Boss 条目永远不会以此方式被克隆。因此额外生物的数量大致为ceil(min(waveNumber, listSize) / 2):第 1 波多 1 只,第 3-4 波多 2 只,第 9-10 波多 5 只,第 15-16 波多 8 只,以此类推,直到波次编号超过列表长度。
一波内部的生成节奏为 min(200 / totalEntities, 20) 刻,而运行时在放出每只生物之前会等待该值的两倍。horde 波次会把间隔减半,以两倍于正常的速率放出它们的生物。每只生物在生成时都会随机挑选关卡的某个起点格。
消息块格式
prewaveMessages 和 waveMessages 都接受一个 map 列表:
prewaveMessages:
- wave: 1
message:
- "&aWelcome! Build a couple of basic towers along the path."
- wave: 5
message:
- "&6Heads up: a boss is coming next wave."
prewaveMessages 在该波次的建造阶段开始时运行。waveMessages 在防御阶段开始的那一刻运行。
波次生命周期
一次会话会经历以下状态:
STARTING— 玩家第一次运行/etd start之前。CONSTRUCTION_PHASE— 防御阶段之间的 10 秒建造窗口。DEFENSIVE_PHASE— 敌人正在生成并沿路径行走。ENDING— 玩家退出、失败,或关卡用尽了所有波次。
除非教程将其保持(请参阅教程关卡),否则建造阶段始终持续 10 秒。
波次结束行为:
- 完成一波将奖励
waveNumber * 10金币。 - 如果你在波次中未损失生命,将获得“完美”奖励,其价值为波次奖励的一半(
waveNumber * 10 * 0.5)。现在公布的数字与实际授予的金币一致。 - 每一波只能结算一次 —— 如果某一波因故重复上报完成,第二次会被忽略;而一旦会话进入结束流程,就不会再有任何结算。
- 每一波结束后会公布下一波的修饰符列表。
关卡何时结束
只有当下一个波次编号作为键存在于 waveEntities 中时,会话才会继续推进,因此波次编号必须从 1 开始连续排列。当下一个编号缺失时:
- 如果文件定义了
suddenDeathWaveEntities,本局会进入突袭模式; - 否则关卡会立即结束,且不会把那个从未运行的波次计算在内。持久化的最高分和通关标题使用的是玩家实际打过的最后一波。
突袭模式
如果定义了 suddenDeathWaveEntities,关卡会继续运行至已配置波次列表之外。
突袭池是按已配置的波次编号轮换的,而不是按一个递增计数器:每次需要一个突袭波次时,EternalTD 会在池中挑选大于当前编号的最小 wave= 编号,若没有更大的编号则回绕到配置中最小的编号。因此该池不必编号为 1, 2, 3, ... —— 存在间隔或从任意编号开始都能正确轮换。
显示的波次编号会从常规波次列表继续向上累加;只有被生成的池条目会轮换。
波次实体的元素属性
每一波都有其各自的元素属性,按波次轮换:
- 第 1 波 → 火
- 第 2 波 → 风
- 第 3 波 → 水
- 第 4 波 → 土
- (然后重复)
当波次实体生成时,有 waveNumber / 100 的几率使该实体继承该波次的元素属性,显示为漂浮在生物上方的彩色标签。
元素伤害规则由塔的 DamageTower 类处理:
- 相同属性的攻击者对相同属性的目标 —— 0.5× 伤害(抗性)。
- 相对的单一元素(火对水、风对土)—— 2× 伤害(暴击)。
- 融合属性(熔岩、爆裂、风暴、淤泥)遵循成对的相互作用;完整矩阵请参阅源代码。
- 无属性的塔对任何目标造成 1× 伤害。
当基础塔被具有相互组合的元素属性的辅助塔接触时,会形成融合属性:
| 组合 | 产生的融合 |
|---|---|
| 火 + 土 | 熔岩 |
| 火 + 风 | 爆裂 |
| 水 + 风 | 风暴 |
| 水 + 土 | 淤泥 |
冲突规则比看上去更窄:
- 同一座塔上的土 + 风总是会让它恢复为无属性,无论还附加了什么。
- 火 + 水只有在同时存在三种或更多不同属性时才会恢复为无属性。一座恰好被一个火辅助塔和一个水辅助塔接触的塔,会任意保留两者之一,因为代码会落到“取集合中的第一个属性”,而那个集合是无序的。
- 无属性的辅助塔(Spyglass、Gold Mine)绝不会影响结果;只要附加了任何有属性的塔,它们就会从集合中被剔除。
生命值、护甲与赏金缩放
WaveEntity 在生成时按下面这个确切顺序应用各步骤:
- 基础生命值从
0.5起步并随波次增长:health = 0.5 + ((wave - 1)^1.2) / 2。 - Boss 实体在此基础上再乘以
baseMobAmount × 0.5。 - Horde 实体的生命值减半。
- 赏金在这里计算,为
ceil(health)——在healthMultiplier之前,也在 air 减半之前。treasure条目随后使其翻倍。 maxHealth = health × healthMultiplier。- Air 实体的
maxHealth再次减半。 - 护甲仅从第 10 波开始出现,设为
maxHealth / 80。
第 4 步的顺序很重要:healthMultiplier 为 3.0 会让敌人的生命值变成三倍,但不会改变它的金币收益;而 air 敌人尽管只有一半生命值,赏金却与其地面同类相同。Gold Mine 辅助塔会在致命一击的那一刻把它的加成叠加到赏金上。
移动速度为:
speed = 0.3 × (1 - slow)
× 1.5 × (1 - slow) if fast
× 0.5 if air
+ wave / 1000
末尾的 wave / 1000 项意味着无论敌人带有什么标记,它们每一波都会变快一丁点;而且这一项是在 air 与减速乘数之后施加的,不会被它们缩放。
分裂小怪(Splitterlings)
从第 20 波开始,非 air 敌人在死亡时会额外生成小型生物(“splitterlings”)。
- 数量:每次击杀生成
floor(wave / 20)个。 - 如果父实体是
CAVE_SPIDER,分裂小怪为SILVERFISH。否则为CAVE_SPIDER。 - 分裂小怪以父实体波次的
wave / 2生成,因此足够深入的运行仍可能让分裂小怪在其自身死亡时再链式生成更多分裂小怪。 - 分裂小怪死亡时不给予金币,且 air 敌人永远不会生成分裂小怪。
教程关卡特殊情况
捆绑的教程地图通过硬编码的教程波次脚本运行:
- 在你于高亮方格上放置完所需的精确塔之前,建造阶段不会自动结束。
- 硬编码的塔由所瞄准网格方格下方的彩色混凝土补丁标示,若安装了 FMM,则在其上方还会漂浮一个向下的红色箭头模型。
- 教程会在前几波注入额外金币,确保脚本化的塔阵容始终买得起:第 1、2、3 波各
+100,第 4 波+200。之后的波次没有额外金币。 - 每个所需塔的方格都会按它要求的塔类型着色:基础塔为绿色混凝土,Barricade 为棕色,Sugar 为白色,Spyglass 为青色,Beam Generator 为黄色,Explosion Factory 为红色,Ice Box 为蓝色,Armor Crusher 为灰色,Gold Mine 为橙色,Obsidian Quarry 为紫色,其他一律为黑色。
玩家生命与金币
- 起始生命:20。
- 起始金币:150。
- Boss 生物到达终点会消耗 5 条生命。其他所有生物消耗 1 条生命。
- 作弊(
/etd cheat)会把金币设为10,000,000、生命设为1,000,000,并将该会话标记为已作弊(用于最高分目的)。把作弊模式切回关闭并不会恢复原来的数值,而且该会话的作弊标记是永久的。 /etd setwave <n>同样会设置作弊标记,并重设波次奖励的防重复基准,因此你跳到的那一波在完成时仍会正常结算。
最高分追踪
每个关卡配置都会持久化 highscoreWave 和 highscorePlayerName。在非作弊会话结束时,插件会将新的波次编号保存到关卡文件中,如果超过先前的分数则会广播全服消息。