巫妖王之怒版本的服务端里,AI模块的结构不像传奇那样写在一个M2里统一调度,而是拆成了一套类继承体系,外加一个状态机机制在驱动所有怪物的行为。想改怪物AI或者自己做新BOSS,得先搞清楚这套东西怎么组织的。
**继承链的顶层设计**
所有生物AI的根在UnitAI类,再往下分两支。一支走CreatureAI,这是怪物和NPC的主线。另一支走PlayerAI,管玩家的宠物和召唤物。
CreatureAI下面派生了两大类。一类叫ScriptedAI,所有普通怪物和大部分副本小怪都挂在这个下面。另一类叫BossAI,专门给团队副本的首领用,WorldBossAI是从BossAI再派出一层,管艾索雷葛斯和翡翠龙这种野外BOSS。
ScriptedAI的派生类很多:AggressorAI管主动攻击的怪,CombatAI管战斗逻辑,CasterAI管施法者,ArcherAI管弓箭手,PassiveAI管不主动攻击的NPC,CritterAI管松鼠兔子这些携物。每种AI的UpdateAI函数实现不一样,AggressorAI会主动扫描视野内的玩家,PassiveAI的UpdateAI里面几乎是空的。
**BossAI的状态机实现**
BossAI和普通ScriptedAI最大的区别在于它内置了一套状态机,专门处理阶段转换。克尔苏加德从P1转P2转P3,每一阶段触发不同的技能组和召唤逻辑,都在BossAI的事件调度器里控制。
事件调度器是状态机的核心部件,用EventMap来管理。在BossAI的构造函数里用events.ScheduleEvent注册一堆事件,每个事件绑定一个延迟时间。UpdateAI每帧调用的时候检查事件是否到期,到期就执行对应的处理函数。比如冰冠堡垒的炮艇战,NPC的MovementInform函数会检测移动类型和路径点完成状态,走完一段路径就触发下一阶段的事件。
状态机里还有一个关键机制叫EscortState,SmartAI里用位掩码记录护送任务的当前状态:正在护送、正在返回、已暂停,每种状态对应不同的移动和战斗逻辑。
**SmartAI的数据存储与条件判断**
SmartAI类在CreatureAI的基础上加了一套数据存储系统,用aiDataSet这个map来存键值对。脚本里用SetData往里面写数据,GetData读取数据,配合CONDITION_AI_DATA条件可以做复杂的流程控制。
这套机制的意义在于不同脚本之间可以共享状态。比如副本里一个BOSS的AI设置了某段数据,另一个NPC的AI可以通过条件判断来响应,不用全局变量满天飞。
**NullCreatureAI和触发器的特殊处理**
有一种特殊的AI叫NullCreatureAI,名字叫Null但实际上不是空的。它派生自CreatureAI,但大部分函数是空实现,AttackStart里面啥也不干,EnterEvadeMode也是空的。这种AI用在触发器生物和纯装饰性NPC上,这些单位不需要攻击行为,但需要保留接收事件和触发脚本的能力。
NullCreatureAI的Permissible函数会检查生物有没有SpellClick标记或者IsTrigger标记,有的话才允许使用这种AI类型。巫妖王在冰冠堡垒的某些阶段就用的是NullCreatureAI,只触发剧情事件不参与战斗。
**实例副本的AI注册方式**
副本里的BOSS脚本注册方式和野外不同。野外生物直接用RegisterCreatureAI宏注册。副本生物要用带副本名前缀的宏,比如冰冠堡垒的BOSS用RegisterIcecrownCitadelCreatureAI。这个宏会额外关联副本实例的数据,让AI能访问到instanceScript里的BOSS状态和玩家进度。
脚本分配到具体生物上,可以在creature_template表的ScriptName字段填类名,所有该编号的生物都生效。也可以在creature表里针对单只生物填ScriptName,覆盖模板的配置。
**继承链的顶层设计**
所有生物AI的根在UnitAI类,再往下分两支。一支走CreatureAI,这是怪物和NPC的主线。另一支走PlayerAI,管玩家的宠物和召唤物。
CreatureAI下面派生了两大类。一类叫ScriptedAI,所有普通怪物和大部分副本小怪都挂在这个下面。另一类叫BossAI,专门给团队副本的首领用,WorldBossAI是从BossAI再派出一层,管艾索雷葛斯和翡翠龙这种野外BOSS。
ScriptedAI的派生类很多:AggressorAI管主动攻击的怪,CombatAI管战斗逻辑,CasterAI管施法者,ArcherAI管弓箭手,PassiveAI管不主动攻击的NPC,CritterAI管松鼠兔子这些携物。每种AI的UpdateAI函数实现不一样,AggressorAI会主动扫描视野内的玩家,PassiveAI的UpdateAI里面几乎是空的。
**BossAI的状态机实现**
BossAI和普通ScriptedAI最大的区别在于它内置了一套状态机,专门处理阶段转换。克尔苏加德从P1转P2转P3,每一阶段触发不同的技能组和召唤逻辑,都在BossAI的事件调度器里控制。
事件调度器是状态机的核心部件,用EventMap来管理。在BossAI的构造函数里用events.ScheduleEvent注册一堆事件,每个事件绑定一个延迟时间。UpdateAI每帧调用的时候检查事件是否到期,到期就执行对应的处理函数。比如冰冠堡垒的炮艇战,NPC的MovementInform函数会检测移动类型和路径点完成状态,走完一段路径就触发下一阶段的事件。
状态机里还有一个关键机制叫EscortState,SmartAI里用位掩码记录护送任务的当前状态:正在护送、正在返回、已暂停,每种状态对应不同的移动和战斗逻辑。
**SmartAI的数据存储与条件判断**
SmartAI类在CreatureAI的基础上加了一套数据存储系统,用aiDataSet这个map来存键值对。脚本里用SetData往里面写数据,GetData读取数据,配合CONDITION_AI_DATA条件可以做复杂的流程控制。
这套机制的意义在于不同脚本之间可以共享状态。比如副本里一个BOSS的AI设置了某段数据,另一个NPC的AI可以通过条件判断来响应,不用全局变量满天飞。
**NullCreatureAI和触发器的特殊处理**
有一种特殊的AI叫NullCreatureAI,名字叫Null但实际上不是空的。它派生自CreatureAI,但大部分函数是空实现,AttackStart里面啥也不干,EnterEvadeMode也是空的。这种AI用在触发器生物和纯装饰性NPC上,这些单位不需要攻击行为,但需要保留接收事件和触发脚本的能力。
NullCreatureAI的Permissible函数会检查生物有没有SpellClick标记或者IsTrigger标记,有的话才允许使用这种AI类型。巫妖王在冰冠堡垒的某些阶段就用的是NullCreatureAI,只触发剧情事件不参与战斗。
**实例副本的AI注册方式**
副本里的BOSS脚本注册方式和野外不同。野外生物直接用RegisterCreatureAI宏注册。副本生物要用带副本名前缀的宏,比如冰冠堡垒的BOSS用RegisterIcecrownCitadelCreatureAI。这个宏会额外关联副本实例的数据,让AI能访问到instanceScript里的BOSS状态和玩家进度。
脚本分配到具体生物上,可以在creature_template表的ScriptName字段填类名,所有该编号的生物都生效。也可以在creature表里针对单只生物填ScriptName,覆盖模板的配置。

