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的一段代碼: