跳到主要内容

EternalTD 波次与敌人

plugins/EternalTD/waves/ 下的波次文件定义了某关卡的完整敌人阵容,包括普通波次、突袭波次以及可选的波前消息或波次消息。每个关卡配置都通过 wavesConfigFile: 引用一个波次文件。

顶级字段​

字段类型默认值备注
isEnabledbooltrue已禁用的波次文件不会加载;依赖该缺失配置的关卡无法启动
baseMobAmountint20当条目未指定 amount= 时使用的默认数量
waveEntitiesstring list必填按波次列出的敌人条目
suddenDeathWaveEntitiesstring list可选可选的循环波次池,在已配置的波次用尽后运行
prewaveMessageslist of maps可选以当前计数器为键的消息:入场时为 0,第 N 波结束后为 N
waveMessageslist 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
键类型备注
waveint必填。此条目所属的波次编号
entityTypeenum必填。准确的 Bukkit EntityType 枚举值;请选择能够生成的生命实体
healthMultiplierdouble可选,默认 1.0。乘以实体的最大生命值
amountint可选。覆盖此条目的 baseMobAmount
namestring可选。自定义名称字符串。会被解析并保存,但插件目前不会把它应用到生成的生物上(名牌显示的是生命值/护甲条)
resistflag将实体标记为免疫减速
fastflag提高移动速度
treasureflag击杀时的金币赏金翻倍
bossflag使用下述 Boss 数量规则和生命值缩放,每个 Boss 都有血条
hordeflagamount 翻倍,生命值减半
airflag实体在路径上方 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(floor(200 / totalEntities), 20) 刻。普通生成要求计数器大于该间隔的两倍;horde 节奏要求大于整数减半后间隔的两倍。由于比较是严格大于,还会多一个计数器刻,并非恰好两倍。是否使用 horde 节奏取决于波次列表中第一个剩余生物,因此混合普通和 horde 条目会随列表变化而改变节奏。每只生物生成时都会随机选择关卡的一个起点格。

消息块格式​

prewaveMessages 和 waveMessages 都接受一个 map 列表:

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 金币。
  • 如果你在波次中未损失生命,将获得“完美”奖励,其价值为波次奖励的一半(waveNumber * 10 * 0.5)。现在公布的数字与实际授予的金币一致。
  • 每一波只能结算一次 —— 如果某一波因故重复上报完成,第二次会被忽略;而一旦会话进入结束流程,就不会再有任何结算。
  • 波次结束后,若下一波的修饰符字符串非空,就会公布它。它来自第一个配置的敌人,而不是混合波次的所有条目。

关卡何时结束​

只有当下一个波次编号作为键存在于 waveEntities 中时,会话才会继续推进,因此波次编号必须从 1 开始连续排列。当下一个编号缺失时:

  • 如果文件定义了 suddenDeathWaveEntities,本局会进入突袭模式;
  • 否则关卡会立即结束,且不会把那个从未运行的波次计算在内。持久化的最高分和通关标题使用的是玩家实际打过的最后一波。

突袭模式​

如果定义了 suddenDeathWaveEntities,关卡会继续运行至已配置波次列表之外。

突袭池按配置的波次编号轮换。每次需要时,EternalTD 会选择大于当前池键的最小非负键;若没有更大的键,就回到最小键。池计数器初始为 0,因此存在正数键时,配置的键 0 会在第一轮被跳过。请使用正数键;允许编号间隔,且键 0 也不适用于下文的生命值公式。

显示的波次计数器会继续增加。敌人的生命值、护甲、速度、基础赏金及分裂小怪阈值使用所选条目配置的 wave=,不会自动随显示计数器缩放。运行时的额外克隆和元素抽取则使用显示计数器。例如,池条目 10 和 20 即使在显示第 100 波时,也保留各自的敌人数值缩放。下一波查找仍会先检查每个显示编号是否有普通条目,因此先前出现缺号后,仍可能使用后续的普通键。

波次实体的元素属性​

每一波都有其各自的元素属性,按波次轮换:

  • 第 1 波 → 火
  • 第 2 波 → 风
  • 第 3 波 → 水
  • 第 4 波 → 土
  • (然后重复)

普通波次实体生成时,继承波次元素的概率为显示的 waveNumber / 100;从显示第 100 波起,抽取必定成功。彩色标签显示元素。分裂小怪单独创建,不参与此抽取。

元素伤害规则由塔的 DamageTower 类处理:

  • 相同属性的攻击者对相同属性的目标 —— 0.5× 伤害(抗性)。
  • 相对的单一元素(火对水、风对土)—— 2× 伤害(暴击)。
  • 融合属性遵循下表。其他不匹配的组合造成 1× 伤害。
  • 无属性的塔对任何目标造成 1× 伤害。
塔的属性对以下属性造成 2× 伤害对以下属性造成 0.5× 伤害
熔岩风、水土、火、熔岩
爆裂土、水风、火、爆裂
风暴火、土风、水、风暴
淤泥火、风土、水、淤泥

当基础塔被具有相互组合的元素属性的辅助塔接触时,会形成融合属性:

组合产生的融合
火 + 土熔岩
火 + 风爆裂
水 + 风风暴
水 + 土淤泥

冲突规则比看上去更窄:

  • 同一座塔上的土 + 风总是会让它恢复为无属性,无论还附加了什么。
  • 火 + 水只有在同时存在三种或更多不同属性时才会恢复为无属性。一座恰好被一个火辅助塔和一个水辅助塔接触的塔,会任意保留两者之一,因为代码会落到“取集合中的第一个属性”,而那个集合是无序的。
  • 无属性的辅助塔(Spyglass、Gold Mine)绝不会影响结果;只要附加了任何有属性的塔,它们就会从集合中被剔除。

每次重新计算都从基础塔自身的“无属性”元素开始,因此移除最后一座元素辅助塔后,塔会恢复为无属性。

生命值、护甲与赏金缩放​

WaveEntity 生成时使用自身配置的波次编号(分裂小怪则使用父实体波次的一半),依次应用以下步骤:

  1. 基础生命值从 0.5 起步并随波次增长:health = 0.5 + ((wave - 1)^1.2) / 2。
  2. Boss 实体在此基础上再乘以 baseMobAmount × 0.5。
  3. Horde 实体的生命值减半。
  4. 赏金在这里计算,为 ceil(health)——在 healthMultiplier 之前,也在 air 减半之前。treasure 条目随后使其翻倍。
  5. maxHealth = health × healthMultiplier。
  6. Air 实体的 maxHealth 再次减半。
  7. 护甲仅从第 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 和减速倍率之后加上。该值控制生物的移动速度属性。非 Mob 实体的备用逻辑则在每个移动刻朝下一个目的地传送 0.1 格,因此此公式并不是通用的“格/刻”速度。

分裂小怪(Splitterlings)​

从第 20 波开始,非 air 敌人在死亡时会额外生成小型生物(“splitterlings”)。

  • 数量:每次击杀生成 floor(wave / 20) 个。
  • 如果父实体是 CAVE_SPIDER,分裂小怪为 SILVERFISH。否则为 CAVE_SPIDER。
  • 分裂小怪使用 floor(parentWave / 2) 并继承当前路径位置。它们使用构造函数的 0.5 生命值倍率,不继承父实体的标记或元素属性。配置波次足够高时,它们死亡后还可能产生更多分裂小怪。
  • 分裂小怪死亡时不给予金币,且 air 敌人永远不会生成分裂小怪。

教程关卡特殊情况​

tutorial.yml 关卡使用与地图坐标绑定的硬编码脚本:

  • 必须在高亮格放置要求的塔类型;若已有同类塔,则在该格升级。允许出售要求格上的错误塔。在对应脚本阶段,无关的放置、出售和升级会被拒绝。最后一个要求被接受时,会立即请求下一波。
  • 彩色混凝土标示要求格。若 FMM 和 reddownarrow 模型可用,每格上方的红箭头会指示所需的塔或升级。
  • 第 1、2、3 波结束并进入建造阶段时,教程增加 +100 金币;第 4 波后增加 +200。这是额外收入,并非保证买得起。其他波次编号没有这笔补充。
  • 每个所需塔的方格都会按它要求的塔类型着色:基础塔为绿色混凝土,Barricade 为棕色,Sugar 为白色,Spyglass 为青色,Beam Generator 为黄色,Explosion Factory 为红色,Ice Box 为蓝色,Armor Crusher 为灰色,Gold Mine 为橙色,Obsidian Quarry 为紫色,其他一律为黑色。
  • 在每个脚本阶段,一条绿色 Boss 血条会以 Build towers! done/total! 的形式统计已放置的所需塔数量。教程每两分钟会提醒你可以用 /etd quit 离开;只要还有未完成的要求,它也会重复当前的波前消息。

玩家生命与金币​

  • 起始生命:20。
  • 起始金币:150。
  • Boss 生物到达终点会消耗 5 条生命。其他所有生物消耗 1 条生命。
  • 每次切换 /etd cheat(包括关闭)都会把金币重设为 10,000,000、生命重设为 1,000,000。该会话此后始终没有刷新最高分的资格。
  • /etd setwave <n> 会更改会话计数器和奖励防重复状态,并将本局标记为已作弊。它不会替换当前敌人,也不会立即启动指定波次。下一次转换使用 n + 1。

最高分追踪​

每个关卡配置都会持久化 highscoreWave 和 highscorePlayerName。在非作弊会话结束时,插件会将新的波次编号保存到关卡文件中,如果超过先前的分数则会广播全服消息。