2010-01-19 16:37:49 +01:00
|
|
|
/* Copyright (C) 2008-2010 Trinity <http://www.trinitycore.org/>
|
2008-10-14 11:57:03 -05:00
|
|
|
*
|
|
|
|
|
* Thanks to the original authors: ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
|
|
|
|
|
*
|
2008-10-02 16:23:55 -05:00
|
|
|
* This program is free software licensed under GPL version 2
|
|
|
|
|
* Please see the included DOCS/LICENSE.TXT for more information */
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
#ifndef SC_CREATURE_H
|
|
|
|
|
#define SC_CREATURE_H
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
#include "Creature.h"
|
2009-05-10 16:07:49 -05:00
|
|
|
#include "CreatureAI.h"
|
|
|
|
|
#include "CreatureAIImpl.h"
|
2009-05-17 16:37:03 -05:00
|
|
|
#include "InstanceData.h"
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-06-16 11:45:33 -05:00
|
|
|
#define SCRIPT_CAST_TYPE dynamic_cast
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-06-16 11:45:33 -05:00
|
|
|
#define CAST_PLR(a) (SCRIPT_CAST_TYPE<Player*>(a))
|
|
|
|
|
#define CAST_CRE(a) (SCRIPT_CAST_TYPE<Creature*>(a))
|
|
|
|
|
#define CAST_SUM(a) (SCRIPT_CAST_TYPE<TempSummon*>(a))
|
|
|
|
|
#define CAST_PET(a) (SCRIPT_CAST_TYPE<Pet*>(a))
|
|
|
|
|
#define CAST_AI(a,b) (SCRIPT_CAST_TYPE<a*>(b))
|
2010-07-31 01:41:32 +02:00
|
|
|
#define CAST_INST(a,b) (SCRIPT_CAST_TYPE<a*>(b))
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-06-04 17:42:48 -05:00
|
|
|
#define GET_SPELL(a) (const_cast<SpellEntry*>(GetSpellStore()->LookupEntry(a)))
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-08-08 05:09:27 +02:00
|
|
|
class InstanceData;
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-08-23 22:09:43 -05:00
|
|
|
class SummonList : public std::list<uint64>
|
2008-11-03 10:16:06 -06:00
|
|
|
{
|
2009-05-10 16:07:49 -05:00
|
|
|
public:
|
2010-04-14 23:07:41 +02:00
|
|
|
explicit SummonList(Creature* creature) : me(creature) {}
|
2009-05-10 16:07:49 -05:00
|
|
|
void Summon(Creature *summon) { push_back(summon->GetGUID()); }
|
|
|
|
|
void Despawn(Creature *summon) { remove(summon->GetGUID()); }
|
|
|
|
|
void DespawnEntry(uint32 entry);
|
|
|
|
|
void DespawnAll();
|
|
|
|
|
void DoAction(uint32 entry, uint32 info);
|
2009-05-13 10:54:11 -05:00
|
|
|
void DoZoneInCombat(uint32 entry = 0);
|
2009-05-10 16:07:49 -05:00
|
|
|
private:
|
2010-04-14 23:07:41 +02:00
|
|
|
Creature *me;
|
2008-11-03 10:16:06 -06:00
|
|
|
};
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-02-05 00:31:28 +01:00
|
|
|
struct ScriptedAI : public CreatureAI
|
2008-10-02 16:23:55 -05:00
|
|
|
{
|
2009-08-16 21:46:31 +02:00
|
|
|
explicit ScriptedAI(Creature* pCreature);
|
2010-01-12 20:51:59 +01:00
|
|
|
virtual ~ScriptedAI() {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//*************
|
|
|
|
|
//CreatureAI Functions
|
|
|
|
|
//*************
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-10-27 21:28:20 -07:00
|
|
|
void AttackStartNoMove(Unit *pTarget);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
// Called at any Damage from any attacker (before damage apply)
|
2010-04-19 09:26:37 +02:00
|
|
|
void DamageTaken(Unit* /*pDone_by*/, uint32& /*uiDamage*/) {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Called at World update tick
|
|
|
|
|
void UpdateAI(const uint32);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Called at creature death
|
2010-04-19 09:26:37 +02:00
|
|
|
void JustDied(Unit* /*who*/){}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Called at creature killing another unit
|
2010-04-19 09:26:37 +02:00
|
|
|
void KilledUnit(Unit* /*who*/){}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
// Called when the creature summon successfully other creature
|
2010-04-07 22:59:46 +02:00
|
|
|
void JustSummoned(Creature*) {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
// Called when a summoned creature is despawned
|
2009-08-14 19:45:06 +02:00
|
|
|
void SummonedCreatureDespawn(Creature*) {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
// Called when hit by a spell
|
2010-04-19 09:26:37 +02:00
|
|
|
void SpellHit(Unit* /*caster*/, const SpellEntry * /*spell*/) {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-18 11:50:02 -05:00
|
|
|
// Called when spell hits a target
|
2010-04-19 09:26:37 +02:00
|
|
|
void SpellHitTarget(Unit * /*pTarget*/, const SpellEntry * /*spell*/) {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Called at waypoint reached or PointMovement end
|
2010-04-19 09:26:37 +02:00
|
|
|
void MovementInform(uint32 /*type*/, uint32 /*id*/){}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-11-05 20:51:05 -06:00
|
|
|
// Called when AI is temporarily replaced or put back when possess is applied or removed
|
2010-04-19 09:26:37 +02:00
|
|
|
void OnPossess(bool /*apply*/) {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//*************
|
|
|
|
|
// Variables
|
|
|
|
|
//*************
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Pointer to creature we are manipulating
|
2010-04-14 23:07:41 +02:00
|
|
|
Creature* me;
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-05 12:10:02 -05:00
|
|
|
//For fleeing
|
|
|
|
|
bool IsFleeing;
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//*************
|
|
|
|
|
//Pure virtual functions
|
|
|
|
|
//*************
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Called at creature reset either by death or evade
|
2009-04-13 17:53:09 -05:00
|
|
|
void Reset() {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Called at creature aggro either by MoveInLOS or Attack Start
|
2010-04-19 09:26:37 +02:00
|
|
|
void EnterCombat(Unit* /*who*/) {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//*************
|
|
|
|
|
//AI Helper Functions
|
|
|
|
|
//*************
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-25 11:40:10 -05:00
|
|
|
//Start movement toward victim
|
2009-08-14 19:45:06 +02:00
|
|
|
void DoStartMovement(Unit* pVictim, float fDistance = 0, float fAngle = 0);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-25 11:40:10 -05:00
|
|
|
//Start no movement on victim
|
2009-08-14 19:45:06 +02:00
|
|
|
void DoStartNoMovement(Unit* pVictim);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Stop attack of current victim
|
|
|
|
|
void DoStopAttack();
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Cast spell by spell info
|
2009-08-14 19:45:06 +02:00
|
|
|
void DoCastSpell(Unit* pTarget, SpellEntry const* pSpellInfo, bool bTriggered = false);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Plays a sound to all nearby players
|
2009-08-06 17:36:32 +02:00
|
|
|
void DoPlaySoundToSet(WorldObject* pSource, uint32 sound);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Drops all threat to 0%. Does not remove players from the threat list
|
|
|
|
|
void DoResetThreat();
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-08-14 19:45:06 +02:00
|
|
|
float DoGetThreat(Unit* u);
|
|
|
|
|
void DoModifyThreatPercent(Unit* pUnit, int32 pct);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-08-14 19:45:06 +02:00
|
|
|
void DoTeleportTo(float fX, float fY, float fZ, uint32 uiTime = 0);
|
2009-05-13 10:54:11 -05:00
|
|
|
void DoTeleportTo(const float pos[4]);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-04-19 09:26:37 +02:00
|
|
|
void DoAction(const int32 /*param*/) {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Teleports a player without dropping threat (only teleports to same map)
|
2009-08-14 19:45:06 +02:00
|
|
|
void DoTeleportPlayer(Unit* pUnit, float fX, float fY, float fZ, float fO);
|
|
|
|
|
void DoTeleportAll(float fX, float fY, float fZ, float fO);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Returns friendly unit with the most amount of hp missing from max hp
|
2009-08-14 19:45:06 +02:00
|
|
|
Unit* DoSelectLowestHpFriendly(float fRange, uint32 uiMinHPDiff = 1);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Returns a list of friendly CC'd units within range
|
2009-08-14 19:45:06 +02:00
|
|
|
std::list<Creature*> DoFindFriendlyCC(float fRange);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Returns a list of all friendly units missing a specific buff within range
|
2009-08-14 19:45:06 +02:00
|
|
|
std::list<Creature*> DoFindFriendlyMissingBuff(float fRange, uint32 uiSpellId);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-04-14 23:07:41 +02:00
|
|
|
//Return a player with at least minimumRange from me
|
2009-07-24 05:27:49 +02:00
|
|
|
Player* GetPlayerAtMinimumRange(float fMinimumRange);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-04-14 23:07:41 +02:00
|
|
|
//Spawns a creature relative to me
|
2009-08-14 19:45:06 +02:00
|
|
|
Creature* DoSpawnCreature(uint32 uiId, float fX, float fY, float fZ, float fAngle, uint32 uiType, uint32 uiDespawntime);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Selects a unit from the creature's current aggro list
|
2009-10-27 21:28:20 -07:00
|
|
|
Unit* SelectUnit(SelectAggroTarget pTarget, uint32 uiPosition);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-08-06 05:11:28 +02:00
|
|
|
bool HealthBelowPct(uint64 pct) const { return me->GetHealth() * 100 < me->GetMaxHealth() * pct; }
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Returns spells that meet the specified criteria from the creatures spell list
|
2010-04-19 17:04:28 +02:00
|
|
|
SpellEntry const* SelectSpell(Unit* Target, uint32 School, uint32 Mechanic, SelectTargetType Targets, uint32 PowerCostMin, uint32 PowerCostMax, float RangeMin, float RangeMax, SelectEffect Effect);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
//Checks if you can cast the specified spell
|
2009-08-14 19:45:06 +02:00
|
|
|
bool CanCast(Unit* pTarget, SpellEntry const* pSpell, bool bTriggered = false);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-04-19 21:16:11 +02:00
|
|
|
void SetEquipmentSlots(bool bLoadDefault, int32 uiMainHand = EQUIP_NO_CHANGE, int32 uiOffHand = EQUIP_NO_CHANGE, int32 uiRanged = EQUIP_NO_CHANGE);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-08-13 02:48:34 +02:00
|
|
|
//Generally used to control if MoveChase() is to be used or not in AttackStart(). Some creatures does not chase victims
|
2009-05-19 21:03:43 +02:00
|
|
|
void SetCombatMovement(bool CombatMove);
|
2009-08-13 02:48:34 +02:00
|
|
|
bool IsCombatMovement() { return m_bCombatMovement; }
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-08-08 21:29:12 +02:00
|
|
|
bool EnterEvadeIfOutOfCombatArea(const uint32 uiDiff);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-01-12 20:51:59 +01:00
|
|
|
// return true for heroic mode. i.e.
|
2010-04-07 18:09:10 +02:00
|
|
|
// - for dungeon in mode 10-heroic,
|
|
|
|
|
// - for raid in mode 10-Heroic
|
2010-01-12 20:51:59 +01:00
|
|
|
// - for raid in mode 25-heroic
|
|
|
|
|
// DO NOT USE to check raid in mode 25-normal.
|
|
|
|
|
bool IsHeroic() { return m_heroicMode; }
|
|
|
|
|
|
|
|
|
|
// return the dungeon or raid difficulty
|
|
|
|
|
Difficulty getDifficulty() { return m_difficulty; }
|
|
|
|
|
|
|
|
|
|
template<class T> inline
|
|
|
|
|
const T& DUNGEON_MODE(const T& normal5, const T& heroic10)
|
|
|
|
|
{
|
|
|
|
|
switch(m_difficulty)
|
|
|
|
|
{
|
|
|
|
|
case DUNGEON_DIFFICULTY_NORMAL:
|
|
|
|
|
return normal5;
|
|
|
|
|
case DUNGEON_DIFFICULTY_HEROIC:
|
|
|
|
|
return heroic10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return heroic10;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T> inline
|
|
|
|
|
const T& RAID_MODE(const T& normal10, const T& normal25)
|
|
|
|
|
{
|
|
|
|
|
switch(m_difficulty)
|
|
|
|
|
{
|
|
|
|
|
case RAID_DIFFICULTY_10MAN_NORMAL:
|
|
|
|
|
return normal10;
|
|
|
|
|
case RAID_DIFFICULTY_25MAN_NORMAL:
|
|
|
|
|
return normal25;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return normal25;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
template<class T> inline
|
|
|
|
|
const T& RAID_MODE(const T& normal10, const T& normal25, const T& heroic10, const T& heroic25)
|
|
|
|
|
{
|
|
|
|
|
switch(m_difficulty)
|
|
|
|
|
{
|
|
|
|
|
case RAID_DIFFICULTY_10MAN_NORMAL:
|
|
|
|
|
return normal10;
|
|
|
|
|
case RAID_DIFFICULTY_25MAN_NORMAL:
|
|
|
|
|
return normal25;
|
|
|
|
|
case RAID_DIFFICULTY_10MAN_HEROIC:
|
|
|
|
|
return heroic10;
|
|
|
|
|
case RAID_DIFFICULTY_25MAN_HEROIC:
|
|
|
|
|
return heroic25;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return heroic25;
|
|
|
|
|
}
|
|
|
|
|
|
2009-08-08 21:29:12 +02:00
|
|
|
private:
|
2009-08-13 02:48:34 +02:00
|
|
|
bool m_bCombatMovement;
|
2009-08-08 21:29:12 +02:00
|
|
|
uint32 m_uiEvadeCheckCooldown;
|
2010-04-07 18:09:10 +02:00
|
|
|
|
2010-01-12 20:51:59 +01:00
|
|
|
bool m_heroicMode;
|
|
|
|
|
Difficulty m_difficulty;
|
2008-10-02 16:23:55 -05:00
|
|
|
};
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-02-05 00:31:28 +01:00
|
|
|
struct Scripted_NoMovementAI : public ScriptedAI
|
2008-10-02 16:23:55 -05:00
|
|
|
{
|
|
|
|
|
Scripted_NoMovementAI(Creature* creature) : ScriptedAI(creature) {}
|
2010-01-12 20:51:59 +01:00
|
|
|
virtual ~Scripted_NoMovementAI() {}
|
2008-10-02 16:23:55 -05:00
|
|
|
|
2010-04-14 23:07:41 +02:00
|
|
|
//Called at each attack of me by any victim
|
2009-06-04 17:42:48 -05:00
|
|
|
void AttackStart(Unit* who);
|
2008-10-02 16:23:55 -05:00
|
|
|
};
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2010-02-05 00:31:28 +01:00
|
|
|
struct BossAI : public ScriptedAI
|
2009-05-10 22:48:22 -05:00
|
|
|
{
|
2009-05-17 16:37:03 -05:00
|
|
|
BossAI(Creature *c, uint32 id);
|
2010-01-12 20:51:59 +01:00
|
|
|
virtual ~BossAI() {}
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-05-17 16:37:03 -05:00
|
|
|
const uint32 bossId;
|
2009-05-10 22:48:22 -05:00
|
|
|
EventMap events;
|
|
|
|
|
SummonList summons;
|
2009-05-17 16:37:03 -05:00
|
|
|
InstanceData * const instance;
|
|
|
|
|
const BossBoundaryMap * const boundary;
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-05-10 22:48:22 -05:00
|
|
|
void JustSummoned(Creature *summon);
|
|
|
|
|
void SummonedCreatureDespawn(Creature *summon);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-05-10 22:48:22 -05:00
|
|
|
void UpdateAI(const uint32 diff) = 0;
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-05-10 22:48:22 -05:00
|
|
|
void Reset() { _Reset(); }
|
2010-04-19 09:26:37 +02:00
|
|
|
void EnterCombat(Unit * /*who*/) { _EnterCombat(); }
|
|
|
|
|
void JustDied(Unit * /*killer*/) { _JustDied(); }
|
2009-05-27 23:26:08 -05:00
|
|
|
void JustReachedHome() { me->setActive(false); }
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-05-17 16:37:03 -05:00
|
|
|
protected:
|
|
|
|
|
void _Reset();
|
|
|
|
|
void _EnterCombat();
|
|
|
|
|
void _JustDied();
|
2009-05-27 23:26:08 -05:00
|
|
|
void _JustReachedHome() { me->setActive(false); }
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-05-17 16:37:03 -05:00
|
|
|
bool CheckInRoom()
|
|
|
|
|
{
|
2010-04-07 19:14:10 +02:00
|
|
|
if (CheckBoundary(me))
|
2009-05-17 16:37:03 -05:00
|
|
|
return true;
|
|
|
|
|
EnterEvadeMode();
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
bool CheckBoundary(Unit *who);
|
2009-05-26 19:55:41 -05:00
|
|
|
void TeleportCheaters();
|
2009-05-10 22:48:22 -05:00
|
|
|
};
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2009-11-22 00:46:38 -08:00
|
|
|
// SD2 grid searchers.
|
|
|
|
|
Creature *GetClosestCreatureWithEntry(WorldObject *pSource, uint32 uiEntry, float fMaxSearchRange, bool bAlive = true);
|
|
|
|
|
GameObject *GetClosestGameObjectWithEntry(WorldObject *pSource, uint32 uiEntry, float fMaxSearchRange);
|
|
|
|
|
void GetCreatureListWithEntryInGrid(std::list<Creature*>& lList, WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange);
|
|
|
|
|
void GetGameObjectListWithEntryInGrid(std::list<GameObject*>& lList, WorldObject* pSource, uint32 uiEntry, float fMaxSearchRange);
|
2009-10-17 15:51:44 -07:00
|
|
|
|
2008-10-02 16:23:55 -05:00
|
|
|
#endif
|
2009-02-17 20:07:49 -06:00
|
|
|
|