TrinityCore 自定义副本制作实战:从设计到实现 原创
温馨提示:
本文最后更新于 2026-04-01,已超过 0 天没有更新。
若文章内的图片失效(无法正常加载),请留言反馈或直接 联系我。
前言
自定义副本是魔兽世界模拟器的核心玩法之一。一个精心设计的副本可以大大提升玩家的游戏体验。本文将详细介绍如何在 TrinityCore 中制作自定义副本,从设计理念到脚本实现,手把手教你打造属于自己的副本。
一、副本设计规划
1.1 副本定位
在开始制作前,需要明确副本的定位:
| 要素 | 说明 | 示例 |
|---|---|---|
| 等级范围 | 适合的玩家等级 | 60-70 级 |
| 玩家人数 | 5 人/10 人/25 人 | 5 人英雄本 |
| 副本时长 | 预计通关时间 | 30-45 分钟 |
| 难度等级 | 简单/中等/困难 | 中等 |
| 主题风格 | 副本背景故事 | 龙族巢穴 |
1.2 副本结构设计
副本结构示例:
┌─────────────────────────────────────┐
│ 入口大厅 │
│ │ │
│ ▼ │
│ ┌────┴────┐ │
│ │ BOSS1 │ │
│ │ 小怪区 │ │
│ └────┬────┘ │
│ │ │
│ ┌────┴────┐ │
│ │ 通道 │ │
│ └────┬────┘ │
│ │ │
│ ┌─────────┴─────────┐ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────┐ ┌─────┐ │
│ │BOSS2│ │BOSS3│ │
│ └──┬──┘ └──┬──┘ │
│ │ │ │
│ └────────┬────────┘ │
│ │ │
│ ▼ │
│ ┌────┴────┐ │
│ │ 最终 BOSS│ │
│ │ 宝藏 │ │
│ └─────────┘ │
└─────────────────────────────────────┘
1.3 BOSS 技能设计
BOSS1:龙族守卫(入门 BOSS)
| 技能名称 | 效果 | 冷却时间 | 应对策略 |
|---|---|---|---|
| 龙息 | 前方锥形范围伤害 | 10 秒 | 坦克调整面向 |
| 尾击 | 后方范围击退 | 8 秒 | DPS 站侧面 |
| 龙鳞护甲 | 减伤 50% | 30 秒 | 停手或驱散 |
BOSS2:暗影法师(机制 BOSS)
| 技能名称 | 效果 | 冷却时间 | 应对策略 |
|---|---|---|---|
| 暗影箭雨 | 全员范围伤害 | 5 秒 | 治疗群刷 |
| 法力护盾 | 吸收伤害 | 20 秒 | 打破护盾 |
| 传送 | 随机传送玩家 | 15 秒 | 快速归位 |
| 召唤小怪 | 召唤 2 个元素 | 40 秒 | 优先击杀 |
最终 BOSS:龙族之王(挑战 BOSS)
| 技能名称 | 效果 | 冷却时间 | 应对策略 |
|---|---|---|---|
| 龙焰风暴 | 全场持续伤害 | 60 秒 | 躲掩体 |
| 震慑咆哮 | 全员眩晕 3 秒 | 45 秒 | 徽章解控 |
| 阶段转换 | 30% 血量狂暴 | 一次 | 爆发 RUSH |
二、数据库实现
2.1 创建副本入口
-- 1. 创建游戏对象(副本入口)
INSERT INTO gameobject_template (
entry, type, displayId, name,
faction, flags, data0, data1
) VALUES (
200001, -- 对象 ID
22, -- 类型:副本入口
123456, -- 显示 ID
'龙族巢穴入口', -- 名称
0, -- 阵营
0, -- 标志
1, -- 数据 0:副本 ID
5 -- 数据 1:难度
);
-- 2. 放置副本入口
INSERT INTO gameobject (
guid, id, map, zoneId, areaId,
spawnMask, phaseMask,
position_x, position_y, position_z, orientation
) VALUES (
100001, -- GUID
200001, -- 对象 ID
0, -- 地图:东部王国
0, -- 区域
0, -- 地区
1, -- 生成掩码
1, -- 相位掩码
-8800.00, -- X 坐标
600.00, -- Y 坐标
100.00, -- Z 坐标
1.57 -- 朝向
);
2.2 创建副本地图
-- 1. 创建地图记录
INSERT INTO map_template (
Id, MapType, Name,
MinLevel, MaxLevel,
MaxPlayers, ResetTime
) VALUES (
1001, -- 地图 ID
5, -- 地图类型:5 人副本
'龙族巢穴', -- 地图名称
60, -- 最低等级
70, -- 最高等级
5, -- 最大玩家数
86400 -- 重置时间:24 小时
);
-- 2. 设置副本难度
INSERT INTO dungeon_encounter (
mapid, difficulty, order_index, bit
) VALUES
(1001, 0, 1, 1), -- 普通难度
(1001, 1, 1, 2); -- 英雄难度
2.3 创建 NPC 和怪物
-- 1. 创建 BOSS1:龙族守卫
INSERT INTO creature_template (
entry, name, subname,
minlevel, maxlevel,
faction, npcflag,
minhealth, maxhealth,
mingold, maxgold,
InhabitType, ScriptName
) VALUES (
300001, -- 生物 ID
'龙族守卫', -- 名称
'副本 BOSS', -- 副标题
62, 62, -- 等级
14, -- 阵营:敌对
3, -- NPC 标志:可攻击
500000, 500000, -- 血量
0, 0, -- 金钱
4, -- 居住类型:飞行 + 陆地
'boss_dragon_guard' -- 脚本名称
);
-- 2. 创建小怪
INSERT INTO creature_template (
entry, name, minlevel, maxlevel,
faction, minhealth, maxhealth, ScriptName
) VALUES
(300002, '龙族卫士', 60, 60, 14, 50000, 50000, 'mob_dragon_guardian'),
(300003, '龙族法师', 60, 60, 14, 40000, 40000, 'mob_dragon_mage'),
(300004, '龙族牧师', 60, 60, 14, 45000, 45000, 'mob_dragon_priest');
-- 3. 放置怪物
INSERT INTO creature (
guid, id, map,
position_x, position_y, position_z, orientation,
spawntimesecs, spawnmask
) VALUES
-- BOSS1 位置
(400001, 300001, 1001, -8700.00, 500.00, 100.00, 3.14, 7200, 1),
-- 小怪位置
(400002, 300002, 1001, -8750.00, 550.00, 100.00, 0, 7200, 1),
(400003, 300002, 1001, -8750.00, 450.00, 100.00, 0, 7200, 1),
(400004, 300003, 1001, -8800.00, 500.00, 100.00, 0, 7200, 1);
2.4 创建掉落物品
-- 1. 创建掉落物品
INSERT INTO item_template (
entry, name, Quality,
ItemLevel, RequiredLevel,
class, subclass,
InventoryType, MaxDurability
) VALUES
(500001, '龙鳞护手', 4, 65, 60, 4, 4, 10, 120), -- 史诗护手
(500002, '龙族之王法杖', 4, 68, 60, 2, 10, 17, 120), -- 史诗法杖
(500003, '龙焰项链', 3, 63, 60, 4, 3, 2, 120); -- 稀有项链
-- 2. 设置掉落
INSERT INTO loot_template (
Entry, Item, ChanceOrQuestChance,
GroupId, MinCount, MaxCount
) VALUES
-- BOSS1 掉落
(300001, 500001, 15, 0, 1, 1), -- 15% 掉落护手
(300001, 500003, 25, 0, 1, 1), -- 25% 掉落项链
-- 最终 BOSS 掉落
(300005, 500002, 10, 0, 1, 1); -- 10% 掉落法杖
三、脚本编写
3.1 BOSS 脚本模板
/*
* BOSS 脚本:龙族守卫
* 技能:龙息、尾击、龙鳞护甲
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
enum DragonGuardSpells
{
SPELL_DRAGON_BREATH = 100001, // 龙息
SPELL_TAIL_STRIKE = 100002, // 尾击
SPELL_DRAGON_SCALE_ARMOR = 100003, // 龙鳞护甲
};
enum DragonGuardEvents
{
EVENT_DRAGON_BREATH = 1,
EVENT_TAIL_STRIKE = 2,
EVENT_DRAGON_SCALE_ARMOR = 3,
};
class boss_dragon_guard : public CreatureScript
{
public:
boss_dragon_guard() : CreatureScript("boss_dragon_guard") { }
struct boss_dragon_guardAI : public ScriptedAI
{
boss_dragon_guardAI(Creature* creature) : ScriptedAI(creature)
{
Initialize();
}
void Initialize()
{
events.Reset();
}
void EnterCombat(Unit* who) override
{
events.ScheduleEvent(EVENT_DRAGON_BREATH, 10000);
events.ScheduleEvent(EVENT_TAIL_STRIKE, 8000);
events.ScheduleEvent(EVENT_DRAGON_SCALE_ARMOR, 30000);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_DRAGON_BREATH:
DoCastVictim(SPELL_DRAGON_BREATH);
events.ScheduleEvent(EVENT_DRAGON_BREATH, 10000);
break;
case EVENT_TAIL_STRIKE:
DoCastVictim(SPELL_TAIL_STRIKE);
events.ScheduleEvent(EVENT_TAIL_STRIKE, 8000);
break;
case EVENT_DRAGON_SCALE_ARMOR:
DoCastSelf(SPELL_DRAGON_SCALE_ARMOR);
events.ScheduleEvent(EVENT_DRAGON_SCALE_ARMOR, 30000);
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetDragonGuardAI(creature);
}
};
void AddSC_boss_dragon_guard()
{
new boss_dragon_guard();
}
3.2 小怪脚本模板
/*
* 小怪脚本:龙族卫士
* 技能:顺劈斩、雷霆一击
*/
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
enum DragonGuardianSpells
{
SPELL_CLEAVE = 100011, // 顺劈斩
SPELL_THUNDER_CLAP = 100012, // 雷霆一击
};
enum DragonGuardianEvents
{
EVENT_CLEAVE = 1,
EVENT_THUNDER_CLAP = 2,
};
class mob_dragon_guardian : public CreatureScript
{
public:
mob_dragon_guardian() : CreatureScript("mob_dragon_guardian") { }
struct mob_dragon_guardianAI : public ScriptedAI
{
mob_dragon_guardianAI(Creature* creature) : ScriptedAI(creature)
{
Initialize();
}
void Initialize()
{
events.Reset();
}
void EnterCombat(Unit* who) override
{
events.ScheduleEvent(EVENT_CLEAVE, 6000);
events.ScheduleEvent(EVENT_THUNDER_CLAP, 10000);
}
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim())
return;
events.Update(diff);
while (uint32 eventId = events.ExecuteEvent())
{
switch (eventId)
{
case EVENT_CLEAVE:
DoCastVictim(SPELL_CLEAVE);
events.ScheduleEvent(EVENT_CLEAVE, 6000);
break;
case EVENT_THUNDER_CLAP:
DoCastAOE(SPELL_THUNDER_CLAP);
events.ScheduleEvent(EVENT_THUNDER_CLAP, 10000);
break;
}
}
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetDragonGuardianAI(creature);
}
};
void AddSC_mob_dragon_guardian()
{
new mob_dragon_guardian();
}
3.3 编译脚本
# 1. 将脚本文件放入目录
cd trinitycore/src/server/scripts/Custom/
mkdir dragon_lair
cd dragon_lair
# 2. 创建 CMakeLists.txt
cat > CMakeLists.txt << 'EOF'
set(scripts_Custom_DRAGON_LAIR_SRCS
boss_dragon_guard.cpp
mob_dragon_guardian.cpp
dragon_lair.h
)
cu_add_library(scripts_Custom_DRAGON_LAIR ${scripts_Custom_DRAGON_LAIR_SRCS})
四、测试与调试
4.1 测试清单
| 测试项目 | 测试内容 | 预期结果 |
|---|---|---|
| 副本入口 | 进入副本 | 正常传送 |
| NPC 刷新 | BOSS 和小怪刷新 | 位置正确 |
| BOSS 技能 | 技能释放 | 效果正常 |
| 掉落系统 | BOSS 死亡掉落 | 物品正确 |
| 副本重置 | 重置副本 | NPC 重置 |
4.2 调试命令
# GM 命令
# 传送到副本
.gm teleport 1001
# 刷新 NPC
.gm npc spawn 300001
# 设置血量
.gm npc set hp 1000000
# 测试技能
.gm cast self 100001
# 查看日志
tail -f logs/WorldServer.log | grep -i "dragon"
4.3 常见问题
问题 1:BOSS 不释放技能
-- 检查脚本是否编译
-- 检查 ScriptName 是否正确
-- 查看日志错误信息
SELECT ScriptName FROM creature_template WHERE entry=300001;
问题 2:掉落不生效
-- 检查掉落表 Entry 是否匹配
-- 检查掉落几率设置
-- 清除掉落缓存
DELETE FROM creature_loot_template WHERE Entry=300001;
-- 重新添加掉落
总结
制作自定义副本需要:
- 精心设计:副本结构、BOSS 技能、掉落物品
- 数据库配置:地图、NPC、物品、掉落
- 脚本编写:BOSS 行为、技能逻辑
- 充分测试:功能测试、平衡性测试
记住:好的副本设计 = 合理的难度 + 有趣的机制 + 丰厚的奖励!
参考资料
温馨提示: 副本制作需要耐心测试。如有疑问,请在评论区留言或联系管理员。