Skip to content

Commit

Permalink
[12329] EventAI: Add new TargetTypes
Browse files Browse the repository at this point in the history
Add target types:
* TARGET_T_ACTION_INVOKER_OWNER which returns the controlling unit of an action's invoker
* TARGET_T_HOSTILE_RANDOM_PLAYER which returns a random player from the threatlist
* TARGET_T_HOSTILE_RANDOM_NOT_TOP_PLAYER which returns a random player from the threatlist except topmost threat holder

Also remove unused CreatureEventAI::CanCast function
  • Loading branch information
Schmoozerd committed Jan 16, 2013
1 parent e238a12 commit 7b674f2
Show file tree
Hide file tree
Showing 4 changed files with 34 additions and 49 deletions.
5 changes: 5 additions & 0 deletions doc/EventAI.txt
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,7 @@ Parameter 2: Target - The Target Type defining who the creature should cast the
Parameter 3: CastFlags - See Table Below for Cast Flag Bitmask Values. If you are unsure what to set this value at leave it at 0.

The creature will cast a spell specified by a spell ID on a target specified by the target type.
If the spell is normal cast, random target types will select only targets within LOS and in spell range
This is commonly used for NPC's who cast spells.

---------------------
Expand Down Expand Up @@ -875,6 +876,10 @@ Target types are used by certain actions and may effect actions differently
4 TARGET_T_HOSTILE_RANDOM Random Target on The Threat List
5 TARGET_T_HOSTILE_RANDOM_NOT_TOP Any Random Target Except Top Threat
6 TARGET_T_ACTION_INVOKER Unit Who Caused This Event to Occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP)
7 TARGET_T_ACTION_INVOKER_OWNER Unit who is responsible for Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)
8 TARGET_T_HOSTILE_RANDOM_PLAYER Random Player on The Threat List
9 TARGET_T_HOSTILE_RANDOM_NOT_TOP_PLAYER Any Random Player Except Top Threat


=========================================
Cast Flags
Expand Down
57 changes: 21 additions & 36 deletions src/game/CreatureEventAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,8 +522,15 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
}
case ACTION_T_CAST:
{
Unit* target = GetTargetByType(action.cast.target, pActionInvoker);
uint32 selectFlags = 0;
uint32 spellId = 0;
if (!(action.cast.castFlags & (CAST_TRIGGERED | CAST_FORCE_CAST | CAST_FORCE_TARGET_SELF)))
{
spellId = action.cast.spellId;
selectFlags = SELECT_FLAG_IN_LOS;
}

Unit* target = GetTargetByType(action.cast.target, pActionInvoker, spellId, selectFlags);
if (!target)
{
sLog.outDebug("CreatureEventAI: NULL target for ACTION_T_CAST creature entry %u casting spell id %u", m_creature->GetEntry(), action.cast.spellId);
Expand Down Expand Up @@ -597,7 +604,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
((Player*)target)->AreaExploredOrEventHappens(action.quest_event.questId);
break;
case ACTION_T_CAST_EVENT:
if (Unit* target = GetTargetByType(action.cast_event.target, pActionInvoker))
if (Unit* target = GetTargetByType(action.cast_event.target, pActionInvoker, 0, SELECT_FLAG_PLAYER))
if (target->GetTypeId() == TYPEID_PLAYER)
((Player*)target)->CastedCreatureOrGO(action.cast_event.creatureId, m_creature->GetObjectGuid(), action.cast_event.spellId);
break;
Expand Down Expand Up @@ -734,7 +741,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
else
{
// if not available, use pActionInvoker
if (Unit* pTarget = GetTargetByType(action.killed_monster.target, pActionInvoker))
if (Unit* pTarget = GetTargetByType(action.killed_monster.target, pActionInvoker, 0, SELECT_FLAG_PLAYER))
if (Player* pPlayer2 = pTarget->GetCharmerOrOwnerPlayerOrPlayerItself())
pPlayer2->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, m_creature);
}
Expand Down Expand Up @@ -1220,7 +1227,7 @@ inline int32 CreatureEventAI::GetRandActionParam(uint32 rnd, int32 param1, int32
return 0;
}

inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoker)
inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoker, uint32 forSpellId, uint32 selectFlags)
{
switch (Target)
{
Expand All @@ -1229,15 +1236,21 @@ inline Unit* CreatureEventAI::GetTargetByType(uint32 Target, Unit* pActionInvoke
case TARGET_T_HOSTILE:
return m_creature->getVictim();
case TARGET_T_HOSTILE_SECOND_AGGRO:
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1);
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_TOPAGGRO, 1, forSpellId, selectFlags);
case TARGET_T_HOSTILE_LAST_AGGRO:
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO, 0);
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_BOTTOMAGGRO, 0, forSpellId, selectFlags);
case TARGET_T_HOSTILE_RANDOM:
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0);
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, forSpellId, selectFlags);
case TARGET_T_HOSTILE_RANDOM_NOT_TOP:
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1);
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, forSpellId, selectFlags);
case TARGET_T_HOSTILE_RANDOM_PLAYER:
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 0, forSpellId, SELECT_FLAG_PLAYER | selectFlags);
case TARGET_T_HOSTILE_RANDOM_NOT_TOP_PLAYER:
return m_creature->SelectAttackingTarget(ATTACKING_TARGET_RANDOM, 1, forSpellId, SELECT_FLAG_PLAYER | selectFlags);
case TARGET_T_ACTION_INVOKER:
return pActionInvoker;
case TARGET_T_ACTION_INVOKER_OWNER:
return pActionInvoker ? pActionInvoker->GetCharmerOrOwnerOrSelf() : NULL;
default:
return NULL;
};
Expand Down Expand Up @@ -1349,34 +1362,6 @@ void CreatureEventAI::DoScriptText(int32 textEntry, WorldObject* pSource, Unit*
}
}

bool CreatureEventAI::CanCast(Unit* Target, SpellEntry const* Spell, bool Triggered)
{
// No target so we can't cast
if (!Target || !Spell)
return false;

// Silenced so we can't cast
if (!Triggered && (m_creature->hasUnitState(UNIT_STAT_CAN_NOT_REACT_OR_LOST_CONTROL) ||
m_creature->HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PACIFIED)))
return false;

// Check for power
if (!Triggered && m_creature->GetPower((Powers)Spell->powerType) < Spell::CalculatePowerCost(Spell, m_creature))
return false;

SpellRangeEntry const* TempRange = GetSpellRangeStore()->LookupEntry(Spell->rangeIndex);

// Spell has invalid range store so we can't use it
if (!TempRange)
return false;

// Unit is out of range of this spell
if (!m_creature->IsInRange(Target, TempRange->minRange, TempRange->maxRange))
return false;

return true;
}

void CreatureEventAI::ReceiveEmote(Player* pPlayer, uint32 text_emote)
{
if (m_bEmptyList)
Expand Down
19 changes: 7 additions & 12 deletions src/game/CreatureEventAI.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,24 +122,20 @@ enum Target
// Self (m_creature)
TARGET_T_SELF = 0, // Self cast

// Hostile targets (if pet then returns pet owner)
// Hostile targets
TARGET_T_HOSTILE, // Our current target (ie: highest aggro)
TARGET_T_HOSTILE_SECOND_AGGRO, // Second highest aggro (generaly used for cleaves and some special attacks)
TARGET_T_HOSTILE_LAST_AGGRO, // Dead last on aggro (no idea what this could be used for)
TARGET_T_HOSTILE_RANDOM, // Just any random target on our threat list
TARGET_T_HOSTILE_RANDOM_NOT_TOP, // Any random target except top threat

// Invoker targets (if pet then returns pet owner)
// Invoker targets
TARGET_T_ACTION_INVOKER, // Unit who caused this Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)
TARGET_T_ACTION_INVOKER_OWNER, // Unit who is responsible for Event to occur (only works for EVENT_T_AGGRO, EVENT_T_KILL, EVENT_T_DEATH, EVENT_T_SPELLHIT, EVENT_T_OOC_LOS, EVENT_T_FRIENDLY_HP, EVENT_T_FRIENDLY_IS_CC, EVENT_T_FRIENDLY_MISSING_BUFF)

// Hostile targets (including pets)
TARGET_T_HOSTILE_WPET, // Current target (can be a pet)
TARGET_T_HOSTILE_WPET_SECOND_AGGRO, // Second highest aggro (generaly used for cleaves and some special attacks)
TARGET_T_HOSTILE_WPET_LAST_AGGRO, // Dead last on aggro (no idea what this could be used for)
TARGET_T_HOSTILE_WPET_RANDOM, // Just any random target on our threat list
TARGET_T_HOSTILE_WPET_RANDOM_NOT_TOP, // Any random target except top threat

TARGET_T_ACTION_INVOKER_WPET,
// Hostile players
TARGET_T_HOSTILE_RANDOM_PLAYER, // Just any random player on our threat list
TARGET_T_HOSTILE_RANDOM_NOT_TOP_PLAYER, // Any random player from threat list except top threat

TARGET_T_END
};
Expand Down Expand Up @@ -618,10 +614,9 @@ class MANGOS_DLL_SPEC CreatureEventAI : public CreatureAI
void ProcessAction(CreatureEventAI_Action const& action, uint32 rnd, uint32 EventId, Unit* pActionInvoker);
inline uint32 GetRandActionParam(uint32 rnd, uint32 param1, uint32 param2, uint32 param3);
inline int32 GetRandActionParam(uint32 rnd, int32 param1, int32 param2, int32 param3);
inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker);
inline Unit* GetTargetByType(uint32 Target, Unit* pActionInvoker, uint32 forSpellId = 0, uint32 selectFlags = 0);

void DoScriptText(int32 textEntry, WorldObject* pSource, Unit* target);
bool CanCast(Unit* Target, SpellEntry const* Spell, bool Triggered);

bool SpawnedEventConditionsCheck(CreatureEventAI_Event const& event);

Expand Down
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "12328"
#define REVISION_NR "12329"
#endif // __REVISION_NR_H__

0 comments on commit 7b674f2

Please sign in to comment.