AzerothCore 高级脚本开发:从入门到精通 原创
温馨提示:
本文最后更新于 2026-04-02,已超过 2 天没有更新。
若文章内的图片失效(无法正常加载),请留言反馈或直接 联系我。
AzerothCore 是目前最流行的魔兽世界模拟器之一,其强大的脚本系统允许开发者自定义游戏内容。
一、开发环境搭建
1.1 必需工具
- 编译器:Visual Studio 2019+ 或 GCC 9+
- CMake:3.16 或更高版本
- Git:版本控制工具
- MySQL Workbench:数据库管理
1.2 源码编译
git clone https://github.com/AzerothCore/azerothcore-wotlk.git --recursive
mkdir build && cd build
cmake ../ -DCMAKE_INSTALL_PREFIX=../dist
make -j$(nproc)
make install
二、脚本基础结构
2.1 文件组织
my_script/
├── CMakeLists.txt
├── include/my_script.h
├── src/npc_custom.cpp
└── sql/world/my_script.sql
2.2 基础模板
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
class my_custom_npc : public CreatureScript
{
public:
my_custom_npc() : CreatureScript("my_custom_npc") { }
struct my_custom_npcAI : public ScriptedAI
{
void Reset() override { }
void EnterCombat(Unit* who) override { Talk(SAY_AGGRO); }
void UpdateAI(uint32 diff) override
{
if (!UpdateVictim()) return;
DoMeleeAttackIfReady();
}
};
CreatureAI* GetAI(Creature* creature) const override
{
return GetAzerothCoreAI(creature);
}
};
void AddSC_my_custom_script()
{
new my_custom_npc();
}
三、战斗 AI 设计
3.1 技能枚举
enum eSpells
{
SPELL_CLEAVE = 20691,
SPELL_ENRAGE = 8599
};
enum eEvents
{
EVENT_CLEAVE = 1,
EVENT_ENRAGE = 2
};
3.2 事件调度
void Reset() override
{
events.Reset();
events.ScheduleEvent(EVENT_CLEAVE, 8000);
events.ScheduleEvent(EVENT_ENRAGE, 300000);
}
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_ENRAGE:
DoCastSelf(SPELL_ENRAGE);
events.ScheduleEvent(EVENT_ENRAGE, 300000);
break;
}
}
DoMeleeAttackIfReady();
}
四、副本脚本开发
4.1 副本实例管理
class instance_custom_raid : public InstanceMapScript
{
public:
instance_custom_raid() : InstanceMapScript("instance_custom_raid", 500) { }
struct instance_custom_raid_MapScript : public InstanceScript
{
uint64 boss1Guid;
uint32 encounterMask;
void Initialize() override
{
boss1Guid = 0;
encounterMask = 0;
}
void SetBossState(uint32 type, EncounterState state) override
{
if (state == DONE)
encounterMask |= (1 << type);
SaveToDB();
}
};
InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
return new instance_custom_raid_MapScript(map);
}
};
五、调试技巧
5.1 日志输出
LOG_INFO("scripts", "Script loaded successfully!");
LOG_DEBUG("scripts", "Player {} in combat", player->GetName());
LOG_ERROR("scripts", "Failed to load: {}", scriptName);
5.2 GM 命令
.npc info # 查看 NPC 信息
.cast # 施放技能
.quest add # 添加任务
.go xyz # 传送
六、常见问题
编译错误:确保 CMakeLists.txt 正确配置,包含 AC_ADD_SCRIPTS_DIR
脚本不加载:检查 AddSC 函数是否调用,查看服务器日志
NPC 不响应:检查 unit_flags,确认 gossip_menu 已配置
七、实战项目
7.1 自定义传送 NPC
class npc_teleporter : public CreatureScript {
public:
npc_teleporter() : CreatureScript(npc_teleporter) { }
bool OnGossipHello(Player* player, Creature* creature) override {
AddGossipItemFor(player, GOSSIP_ICON_CHAT, 暴风城, 0, 1);
AddGossipItemFor(player, GOSSIP_ICON_CHAT, 奥格瑞玛, 0, 2);
SendGossipMenuFor(player, 1, creature->GetGUID());
return true;
}
bool OnGossipSelect(Player* player, Creature* creature, uint32, uint32 action) override {
switch(action) {
case 1: player->TeleportTo(0, -8833.0f, 663.0f, 95.0f, 0.0f); break;
case 2: player->TeleportTo(1, 1552.0f, -4418.0f, 17.0f, 0.0f); break;
}
CloseGossipMenuFor(player);
return true;
}
};
八、学习资源
- AzerothCore Wiki: https://www.azerothcore.org/wiki/
- GitHub: https://github.com/AzerothCore/azerothcore-wotlk
- Discord: https://discord.gg/azerothcore
多实践是掌握脚本开发的关键。