- 版权类型
- 原创
- 插件中文名称
- WBD团队死斗
- 插件英文名称
- WBDTeamDeathMatch
- 适配版本(Java)
- 最新版本
[MD]
# WBDTeamDeathmatch(WBDTDM)—— 团队死斗模式:无限复活 · 限时击杀赛
> **当前版本:1.2.1** | 适用服务端:Arclight / Paper / Spigot **1.20.1** | 需要 Java 17
>
> WarZBombDefuse 生态下的团队死斗模式。它不是把爆破模式改一改,而是与爆破**完全平行**的另一套玩法:
> 没有回合、没有炸弹,只有连续对抗、无限复活与击杀计数。
>
> 场地坐标、商店配置、物品数据格式全部沿用 WarZBombDefuse —— 你在爆破模式里量好的场地、配好的商店,
> 可以用一条命令直接搬过来。
---
## 这个插件解决什么问题
WarZBombDefuse 的爆破模式是回合制的:每回合重发装备、全灭即负、节奏被回合切得很碎。
想让服务器上多一个「随时进来就能打、死了马上回来」的常驻玩法,用爆破模式改是改不出来的 ——
它的回合状态机、发炸弹、全灭判负,与无限复活天然冲突。
本插件是另起一套:
- 有自己的场地定义、自己的比赛循环、自己的计分与段位
- 与 WarZBombDefuse **互不干扰**,可以同时开服、同时存在(但**不要用同一个场地**,见下文)
- 通过 WBDAddon 复用附加能力,而不是把那些功能重写一遍
---
## 前置依赖
| 依赖 | 类型 | 说明 |
|---|---|---|
| **WarZBombDefuse** | **硬依赖** | 场地坐标、商店配置、物品数据格式全部沿用它的。**缺少时服务端直接不加载本插件**(`plugin.yml` 里声明为 `depend`) |
| **WBDAddon** | 软依赖 | 提供 `WbdAddonApi`。**没装也能正常玩**,只是失去饥饿锁定、JourneyMap 队伍桥接、武器名解析与伤害统计。队友名牌功能需要 **WBDAddon 1.2.1+**,低于此版本该功能会静默失效,插件会在控制台给出警告 |
| **SQLite JDBC** | 服务端自带 | 段位与比赛历史存在 `ranked.db`。Paper / Spigot / Arclight 的 `libraries/` 里都有,**插件不打包**,避免版本冲突 |
> 关于硬依赖为什么用 `depend` 而不是"加载后自己禁用":Bukkit 会**先**按 `plugin.yml` 注册命令、**然后**才调 `onEnable`。
> "加载成功再自己禁用"会留下一个存在于命令表、却永远挂不上执行器的 `/tdm` ——
> 玩家执行任何子命令只看到干巴巴一句 `/tdm help`,控制台干干净净,是最难查的那种故障。
---
## 功能一览
| 模块 | 说明 |
|---|---|
| **比赛循环** | 等待 → 倒计时 → 对战 → 结算 → 自动重开。到击杀目标或时间耗尽即结束,时间到则以击杀数判定 |
| **无限复活** | 阵亡后延时复活并给予短暂无敌;**复活保留背包**,不像爆破那样每回合重发装备 |
| **经济与商店** | 击杀与连杀赚取金钱,在商店买装备;金钱每场重置、有持有上限 |
| **购买区限制** | 必须站在本阵营的购买区内才能开商店,格式与 WBD 的 `buy-zones` 完全一致 |
| **排位段位** | 8 段 × 4 小段,Apex 式计分,含段位保护与赛季软重置 |
| **战后战报** | 每局落盘一份 YAML 战报,同时写库供查询 |
| **战报查询** | `/tdm matchrp <玩家>` 打开箱子界面,点图标在聊天栏展开那一场 |
| **队友名牌** | 队友头顶带 `[队友]` 前缀,**敌人名牌完全隐藏**(原版队伍机制,不需要发包插件) |
| **HUD** | BossBar 显示时间与比分,ActionBar 显示击杀播报,每人一块独立侧边栏计分板 |
---
## 玩法与设计取舍
### 比赛循环
```
WAITING ── 人满 ──> COUNTDOWN ── 倒计时结束 ──> LIVE ── 达标/超时 ──> ENDED ── 延时 ──> WAITING
```
等待阶段就能开商店挑装备,不必干等开场那十秒。中途加入会**立刻投入战斗**并给上保护,避免一进场就被秒。
### 无限复活:为什么保留背包
这是死斗与爆破最本质的区别。玩家在商店里花击杀赚来的钱挑好的枪,不该因为一次阵亡就白买 ——
所以复活**只复位状态、补商店入口,不动背包**。
`respawn.delay-seconds` 可以设为 `0` 实现瞬间复活。这里有个真实的竞态:复活可能抢在"切旁观"之前执行,
那时玩家还卡在死亡界面上,传送与切换游戏模式全部无效,随后到来的重生会把人丢到主城出生点。
插件内部用一个"切旁观尚未完成"的标志解决它,配 `0` 也不会出问题。
### 经济与商店
击杀与连杀赚取金钱(连杀加成有上限,避免高手滚雪球把局面打成一边倒),
在商店购买装备。金钱**每场比赛开始时重置**,跨场带着上一场的钱会让优势一路滚下去。
商店配置与 WarZBombDefuse 通用:
```yaml
shop:
source: wbd # 直接共用 WBD 的商店配置
# source: local # 或用本插件目录下的副本,两边独立维护
```
- `/tdm shopedit [T|CT] [页]` 图形化编辑商店,鼠标摆货、关闭即保存
- `/tdm shop adopt` 把 WBD 的商店配置复制一份过来,之后两边互不影响
- `/tdm exportitem` 把手持物品导出成可贴进配置的完整物品数据
落点规则依次是:`slot-overrides` → 商品 `give-slot` → `material-slots` → `fallback-slot`。
### 购买区限制
必须站在**本阵营的购买区**内才能开商店。判断在三个地方都执行:右键商店物品、`/tdm shop` 命令、以及**点击购买时**。
只查打开时机是不够的 —— 菜单开着的时候玩家可以走出去继续买;只查右键路径也不行,`/tdm shop` 是绕过限制最省事的入口。
---
## 排位段位
- **8 段 × 4 小段**:菜鸟 / 青铜 / 白银 / 黄金 / 铂金 / 钻石 / 大师 / 猎杀
- **Apex 式计分**:`名次分 + 比分差修正 + 击杀分 + 队内排名分 − 入场费`
- 击杀分**封顶 10 杀**:死斗里击杀就是胜负的成因,与名次分共线,不封顶等于把同一件事算两遍
- **中途加入者**只结算击杀分,不扣入场费、不给名次分 —— 否则会奖励"专挑赢面大的局进去蹭分"
- **中途离开处罚**:本局不结算排位分,并**双倍扣除入场费**;**掉线同样受罚**(否则拔网线就成了逃避败场的标准操作)。等待阶段、结算阶段离开以及服务器清场不受罚
- **段位保护**:最低段(菜鸟)RP 不为负;升段后 3 场内有降段保护(`season.yml` 的 `protection` 段可调)
- **赛季软重置**:`新 RP = 基准 + (旧 RP − 基准) / 2`,支持定时自动与 `/tdm season reset` 手动
数据存 SQLite(`ranked.db`,WAL 模式,写不阻塞读),驱动用服务端自带的。
---
## 战后战报
每局结束落盘一份 YAML 到 `plugins/WBDTeamDeathmatch/reports/`,含比分、胜负、每位玩家的击杀/死亡/连杀/收入与段位变化明细。
同时写一份进数据库,供 `/tdm matchrp <玩家>` 查询 —— 命令若去扫目录解析几百个 YAML,玩家随手一敲就把主线程卡住了。
`/tdm matchrp` 是一个 54 格箱子界面,一格一场最近的比赛,图标上带时间、比分、结束原因与你自己的战绩。
**点一下图标**会关闭界面并在聊天栏展开那一场的完整战报,按阵营分块,先展示你所在的那一方,块内按击杀降序。
清理旧战报时**只删自己生成的文件名格式** —— `reports/` 目录里完全可能有服主自己放进去的文件,
按"所有 `.yml` 都是战报"去删就是删用户数据。
---
## 显示
- **BossBar**:比赛时间与双方比分
- **ActionBar**:击杀播报,形如 `[武器名] 受害者 +赏金`,两秒后淡出
- **侧边栏计分板**:**每人一块独立板子**,可显示 `%money%` `%tier%` `%kills%` `%deaths%` `%kd%` 等个人数据
- **队友名牌**:队友带 `[队友]` 前缀,敌人名牌完全隐藏。用的是原版队伍机制,**不需要任何发包插件**
---
## 命令速查
主命令 `/tdm`,别名 `/teamdeathmatch`。
| 权限 | 默认 | 覆盖范围 |
|---|---|---|
| `tdm.use` | 所有人 | 加入、离开、商店、段位与战报查询 |
| `tdm.admin` | OP | 场地管理、强制开局、商店编辑、导出、重载 |
### 玩家命令
| 命令 | 说明 |
|---|---|
| `/tdm join [场地id] [t\|ct]` | 加入比赛。省略场地自动挑一个;省略阵营按人数自动平衡 |
| `/tdm leave` | 离开比赛,位置与背包还原到进入前 |
| `/tdm shop` | 打开装备商店(需在购买区内) |
| `/tdm rank [玩家]` | 查询段位与本赛季战绩,**离线玩家也能查** |
| `/tdm matchrp [玩家]` | 打开比赛战报界面 |
| `/tdm list` | 列出所有场地:id、显示名、启用状态、当前人数 |
| `/tdm status [场地id]` | 查看某场比赛详情 |
| `/tdm help` | 帮助 |
### 管理命令(`tdm.admin`)
| 命令 | 说明 |
|---|---|
| `/tdm import <wbd场地id> [新id]` | 从 WarZBombDefuse 导入坐标、出生点与边界 |
| `/tdm delete <场地id>` | 删除死斗自己的场地配置(**不动 WBD 那边**) |
| `/tdm enable` / `disable <场地id>` | 启用 / 停用场地;`enable` 会**自动在 WBD 侧禁用同名场地** |
| `/tdm start` / `stop [场地id]` | 强制开始 / 结束比赛 |
| `/tdm shopedit [T\|CT] [页]` | 可视化编辑商店 |
| `/tdm shop adopt` | 采用 WarZBombDefuse 的商店配置 |
| `/tdm exportitem` | 把手持物品导出成可贴进配置的物品数据 |
| `/tdm season [reset]` | 查看赛季剩余天数 / 手动软重置 |
| `/tdm reload` | 重载全部配置与场地 |
Tab 补全会按权限过滤,普通玩家看不到管理子命令。
---
## 配置
插件数据目录:`plugins/WBDTeamDeathmatch/`
| 文件 | 内容 |
|---|---|
| `config.yml` | 全局玩法设置(10 个段:`match` / `respawn` / `combat` / `hud` / `economy` / `loadout` / `shop` / `integration` / `teammate` / `reports`) |
| `arenas.yml` | 场地定义,坐标格式与 WBD 完全一致 |
| `season.yml` | 段位表、计分权重、赛季长度与保护规则 |
| `messages.yml` | 全部面向玩家的文案,支持 `%占位符%` |
| `shop.yml` | 商店配置(默认是**空商店**,刻意不带任何武器) |
几个常改的项:
```yaml
match:
target-kills: 50 # 击杀目标,0 表示不设目标
time-limit-seconds: 900 # 时间上限,0 表示不限时
min-players: 2 # 最少开局人数
auto-restart: true # 结算后自动重开
respawn:
delay-seconds: 3 # 复活延时,设 0 可瞬间复活
protection-seconds: 2.0 # 复活无敌时长
break-protection-on-attack: true # 保护期内主动开火立即破保护
economy:
enabled: true
start-money: 800
kill-reward: 300
max-money: 16000
```
每个场地可以在 `arenas.yml` 里覆盖 `target-kills`、`time-limit-seconds`、`countdown-seconds` 等节奏参数,
还能用 `unrank: true` 把训练场、活动场排除在段位之外。
---
## 安装
1. 把 **WarZBombDefuse**、**WBDAddon**(可选)与本插件一起放进 `plugins/`,重启服务器
2. 用 `/wbd create` 与 `/wbd setup` 在爆破模式里把场地量好,然后导入:
```
/tdm import <wbd场地id> # 坐标原样导入
```
3. 核对坐标后启用:
```
/tdm enable <场地id> # 会自动在 WBD 侧禁用同名场地
```
4. 加入:
```
/tdm join <场地id>
```
产物文件名为 `WBDTDM-1.2.1-<git短哈希>-<构建时间戳>.jar`(例如 `WBDTDM-1.2.1-e1785aa-20261013-0250.jar`)。
短哈希与时间戳让同一版本的多次构建不会互相覆盖,也能一眼对应到是哪份代码。
---
## 与 WarZBombDefuse 共存(重要)
> **被死斗使用的场地,必须在 WarZBombDefuse 侧保持 `enabled: false`。**
两个模式同时启用同一个场地时,WBD 的回合循环(倒计时、发炸弹、全灭判负、强制旁观)会和死斗的无限复活**直接打架**,
表现为"玩家莫名其妙变成旁观者""复活后又被传走"这类说不清的现象。
`/tdm enable` 会自动替你处理,启动时也会检查并告警。它走的是 WBD 的控制台命令而不是直接改对方的 YAML ——
后者会丢掉那份文件的注释,也读不到 WBD 的内存状态。
---
## 常见问题
以下几条都是实际踩过并已修复的,列出来是因为它们**都不报错**,只表现为"说不清的怪现象":
| 症状 | 原因 |
|---|---|
| 商店里全是武器 / 装备全挤在第一格 | `shop.source` 指向了没调过落点的配置,或读到 WBD 原版(`give-slot` 多为 `-1`)。可配合 `slot-overrides` / `material-slots` 调整 |
| 发出来的枪不是那把枪 | 商品缺少 `give-data`,只能按材质造空壳。启动日志的"发放数据审计"会点名 |
| 段位永远偏低 | (已修复)结算晚于新一局的清零,会导致全员按 0 击杀结算 |
| 敌人头上还显示名字 | WBDAddon 版本低于 **1.2.1**,队友名牌功能静默失效,控制台有警告 |
| 商店突然打不开 | `buy-zones` 球心坐标不对(落在地底/半空),玩家进不去 |
| `/tdm` 任何子命令都只显示 usage | `onEnable` 中途抛异常,命令执行器没挂上。日志里会有明确的启用失败段落 |
| 玩家卡在死亡界面 | (已修复)`delay-seconds: 0` 时复活抢在切旁观之前执行 |
---
## 已知限制
- **同一场地只能跑一场比赛**:想同时开第二场,请再配一个场地。多实例共享同一份出生点会让复活位置互相打架,收益很小
- **不强制队伍平衡**:玩家手动指定阵营时会被尊重,不管两边人数差多少。需要严格平衡的服务器请用权限约束或赛前协调
- **硬依赖 WarZBombDefuse**:没有它连一份场地都读不出来,插件不会加载
- **段位依赖 SQLite 驱动**:服务端不提供时会**自动降级禁用段位功能**,死斗本体照常运行
---
## 开源协议
本项目以 **GPL-3.0** 开源,与同生态的 WBDAddon 保持一致。
这意味着基于本项目的衍生作品必须以相同条款开源分发,不能改为闭源。仅在自己的服务器上使用不构成分发,不受此约束。
---
## 相关链接与反馈
- 源码 / 问题反馈:https://github.com/DICEALPHAHU/WBDTeamDeathMatch
- WBDAddon(可选依赖,提供饥饿锁定与 JourneyMap 桥接等):https://github.com/DICEALPHAHU/WBDAddon
有问题欢迎回帖或提 Issue,反馈 QQ:**2387629002**
[/MD]