AzerothCore 副本机制详解 – BOSS 技能实现 原创
温馨提示:
本文最后更新于 2026-04-02,已超过 2 天没有更新。
若文章内的图片失效(无法正常加载),请留言反馈或直接 联系我。
副本是 WoW 的核心玩法之一,BOSS 战的设计直接影响玩家体验。本文深入讲解 AzerothCore 中副本机制和 BOSS 技能实现。
一、副本基础架构
1.1 副本类型
- 5 人副本:普通/英雄难度
- 10 人团队:普通/英雄难度
- 25 人团队:普通/英雄难度
- 场景战役:特殊机制副本
1.2 副本实例管理
class instance_blackwing_lair : public InstanceMapScript {
public:
instance_blackwing_lair() : InstanceMapScript("instance_blackwing_lair", 267) {}
struct instance_blackwing_lair_MapScript : public InstanceScript {
uint64 razorgothGUID;
uint64 vaelastraszGUID;
uint64 chromaggusGUID;
uint64 nefarianGUID;
std::vector minionGUIDs;
uint32 encounterMask;
void Initialize() override {
razorgothGUID = 0;
vaelastraszGUID = 0;
chromaggusGUID = 0;
nefarianGUID = 0;
encounterMask = 0;
}
void SetBossState(uint32 type, EncounterState state) override {
if (state == DONE)
encounterMask |= (1 << type);
SaveToDB();
}
std::string GetSaveData() override {
std::ostringstream saveStream;
saveStream << "B W L " << encounterMask;
return saveStream.str();
}
void Load(char const* data) override {
if (!data) return;
char dataHead1, dataHead2, dataHead3;
uint32 data1;
std::istringstream loadStream(data);
loadStream >> dataHead1 >> dataHead2 >> dataHead3 >> data1;
if (dataHead1 == 'B' && dataHead2 == 'W' && dataHead3 == 'L')
encounterMask = data1;
}
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override {
return new instance_blackwing_lair_MapScript(map);
}
};
二、BOSS 技能框架
2.1 技能枚举
enum Spells {
SPELL_CLEAVE = 20691,
SPELL_VOID_BOLT = 35340,
SPELL_SHADOW_FLAME = 29384,
SPELL_BURNING_FURY = 29382,
SPELL_FLAME_BREATH = 29385,
SPELL_ENRAGE = 8599
};
enum Events {
EVENT_CLEAVE = 1,
EVENT_VOID_BOLT = 2,
EVENT_SHADOW_FLAME = 3,
EVENT_ENRAGE = 4
};
enum Phases {
PHASE_ONE = 1,
PHASE_TWO = 2,
PHASE_THREE = 3
};
2.2 BOSS AI 基础
class boss_chromaggus : public CreatureScript {
public:
boss_chromaggus() : CreatureScript("boss_chromaggus") { }
struct boss_chromaggusAI : public ScriptedAI {
boss_chromaggusAI(Creature* creature) : ScriptedAI(creature) {}
void Reset() override {
events.Reset();
summons.DespawnAll();
phase = PHASE_ONE;
healthPercent = 100;
}
void EnterCombat(Unit* who) override {
Talk(SAY_AGGRO);
events.ScheduleEvent(EVENT_CLEAVE, 8000);
events.ScheduleEvent(EVENT_FLAME_BREATH, 15000);
events.ScheduleEvent(EVENT_SHADOW_FLAME, 25000);
}
void JustDied(Unit* killer) override {
Talk(SAY_DEATH);
instance->SetBossState(TYPE_CHROMAGGUS, DONE);
}
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, 8000);
break;
case EVENT_FLAME_BREATH:
DoCastVictim(SPELL_FLAME_BREATH);
events.ScheduleEvent(EVENT_FLAME_BREATH, 15000);
break;
case EVENT_SHADOW_FLAME:
DoCastAOE(SPELL_SHADOW_FLAME);
events.ScheduleEvent(EVENT_SHADOW_FLAME, 25000);
break;
}
}
// 检查阶段转换
CheckPhaseTransition();
DoMeleeAttackIfReady();
}
void CheckPhaseTransition() {
float healthPct = ((float)me->GetHealth() / me->GetMaxHealth()) * 100;
if (healthPct < 30 && phase == PHASE_TWO) {
phase = PHASE_THREE;
Talk(SAY_PHASE_THREE);
events.ScheduleEvent(EVENT_ENRAGE, 1000);
} else if (healthPct < 60 && phase == PHASE_ONE) {
phase = PHASE_TWO;
Talk(SAY_PHASE_TWO);
}
}
private:
EventMap events;
SummonList summons;
uint8 phase;
float healthPercent;
};
CreatureAI* GetAI(Creature* creature) const override {
return GetAzerothCoreAI(creature);
}
};
三、特殊机制实现
3.1 点名技能
void CastTargetedSpell() {
// 随机选择一个玩家
Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100.0f, true);
if (target) {
Talk(SAY_TARGET);
DoCast(target, SPELL_TARGETED_SPELL);
// 标记目标
target->CastSpell(target, SPELL_MARK, true);
}
}
3.2 范围技能
void CastAOESpell() {
std::list<Creature*> targets;
me->GetCreatureListWithEntryInGrid(targets, 0, 50.0f);
for (auto target : targets) {
if (target->IsPlayer()) {
DoCast(target, SPELL_AOE_DAMAGE);
}
}
}
3.3 召唤小怪
void SummonMinions() {
Talk(SAY_SUMMON);
// 在指定位置召唤
me->SummonCreature(NPC_MINION, 1234.5f, 567.8f, 100.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 300000);
me->SummonCreature(NPC_MINION, 1240.0f, 570.0f, 100.0f, 0.0f, TEMPSUMMON_TIMED_DESPAWN, 300000);
events.ScheduleEvent(EVENT_SUMMON_MINIONS, 60000); // 60 秒后再次召唤
}
四、调试技巧
4.1 GM 命令测试
.phase # 查看当前阶段
.phase # 设置阶段
.cast # 测试技能
.npc info # 查看 NPC 信息
.go xyz # 传送到副本
4.2 日志输出
LOG_INFO("scripts", "Boss entered combat");
LOG_DEBUG("scripts", "Casting spell {}", spellId);
LOG_ERROR("scripts", "Failed to find target");
五、总结
副本 BOSS 设计需要平衡难度和趣味性。建议:
- 从简单 BOSS 开始学习
- 多测试技能时间轴
- 注意技能伤害平衡
- 添加适当的机制提示
好的 BOSS 战让玩家既挑战又享受。