CreatureAI这个类并不大,构造函数要传入一个Creature的指针,然后就是20来个接口函数。
构造函数:
explicit CreatureAI(Creature* creature) : m_creature(creature) {}
接口函数不多,可以全部列出来:
// Called if IsVisible(Unit *who) is true at each *who move, reaction at visibility zone enter
virtual void MoveInLineOfSight(Unit *) {}
// Called for reaction at enter to combat if not in combat yet (enemy can be NULL)
virtual void EnterCombat(Unit* /*enemy*/) {}
// Called for reaction at stopping attack at no attackers or targets
virtual void EnterEvadeMode() {}
// Called at reaching home after evade
virtual void JustReachedHome() {}
// Called at any heal cast/item used (call non implemented)
virtual void HealBy(Unit * /*healer*/, uint32 /*amount_healed*/) {}
// Called at any Damage to any victim (before damage apply)
virtual void DamageDeal(Unit * /*done_to*/, uint32 & /*damage*/) {}
// Called at any Damage from any attacker (before damage apply)
// Note: it for recalculation damage or special reaction at damage
// for attack reaction use AttackedBy called for not DOT damage in Unit::DealDamage also
virtual void DamageTaken(Unit * /*done_by*/, uint32 & /*damage*/) {}
// Called when the creature is killed
virtual void JustDied(Unit *) {}
// Called when the creature kills a unit
virtual void KilledUnit(Unit *) {}
// Called when the creature summon successfully other creature
virtual void JustSummoned(Creature* ) {}
virtual void SummonedCreatureDespawn(Creature* /*unit*/) {}
// Called when hit by a spell
virtual void SpellHit(Unit*, const SpellEntry*) {}
// Called when spell hits creature's target
virtual void SpellHitTarget(Unit*, const SpellEntry*) {}
// Called when the creature is target of hostile action: swing, hostile spell landed, fear/etc)
virtual void AttackedBy(Unit* attacker);
// Called when creature is spawned or respawned (for reseting variables)
virtual void JustRespawned() {}
// Called at waypoint reached or point movement finished
virtual void MovementInform(uint32 /*MovementType*/, uint32 /*Data*/) {}
// Called at text emote receive from player
virtual void ReceiveEmote(Player* /*pPlayer*/, uint32 /*text_emote*/) {}
// Called when creature attack expected (if creature can and no have current victim)
// Note: for reaction at hostile action must be called AttackedBy function.
virtual void AttackStart(Unit *) {}
// Is unit visible for MoveInLineOfSight
virtual bool IsVisible(Unit *) const { return false; }
// Called when victim entered water and creature can not enter water
virtual bool canReachByRangeAttack(Unit*) { return false; }
// Called at World update tick
virtual void UpdateAI(const uint32 /*diff*/) {}
可以看到,大部分接口是事件触发和消息通知。UpdateAI我放到最后,这个和别的接口函数不同,是负责AI状态的更新处理。
以CreatureAI为基类,派生出了PetAI、CreatureEventAI、GuardAI、ReactorAI、AggressAI、TotemAI和NullCreatureAI 7类基本AI。Creature的AIM_Initialize()函数,对AI进行初始化,根据Creature的类型选择不同的AI。值得提出的是,Mangos还支持ScriptAI,对于非宠物类的生物支持扩展脚本AI。Mangos的脚本系统我还没有怎么看,有空研究下。
可以看到Mangos的AI设计还是比较传统的,Creature类相当于身体和物理存在,干很多“傻大粗”的事情;AI相当于Creature的大脑,对事件进行响应和处理,指挥着身体物理存在进行反应。
下面可以看下宠物AI的一段代码: