aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xsrc/server/game/AI/CoreAI/UnitAI.cpp46
-rwxr-xr-xsrc/server/game/AI/CoreAI/UnitAI.h26
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp15
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h4
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp4
5 files changed, 87 insertions, 8 deletions
diff --git a/src/server/game/AI/CoreAI/UnitAI.cpp b/src/server/game/AI/CoreAI/UnitAI.cpp
index 476c4fb9c70..82b0f5c7125 100755
--- a/src/server/game/AI/CoreAI/UnitAI.cpp
+++ b/src/server/game/AI/CoreAI/UnitAI.cpp
@@ -23,6 +23,7 @@
#include "SpellAuraEffects.h"
#include "SpellMgr.h"
#include "SpellInfo.h"
+#include "Spell.h"
#include "CreatureAIImpl.h"
void UnitAI::AttackStart(Unit* victim)
@@ -245,3 +246,48 @@ void SimpleCharmedAI::UpdateAI(const uint32 /*diff*/)
if (!target || !charmer->IsValidAttackTarget(target))
AttackStart(charmer->SelectNearestTargetInAttackDistance());
}
+
+SpellTargetSelector::SpellTargetSelector(Unit* caster, uint32 spellId) :
+ _caster(caster), _spellInfo(sSpellMgr->GetSpellForDifficultyFromSpell(sSpellMgr->GetSpellInfo(spellId), caster))
+{
+ ASSERT(_spellInfo);
+}
+
+bool SpellTargetSelector::operator()(Unit const* target) const
+{
+ if (_spellInfo->CheckTarget(_caster, target) != SPELL_CAST_OK)
+ return false;
+
+ // copypasta from Spell::CheckRange
+ uint32 range_type = _spellInfo->RangeEntry ? _spellInfo->RangeEntry->type : 0;
+ float max_range = _caster->GetSpellMaxRangeForTarget(target, _spellInfo);
+ float min_range = _caster->GetSpellMinRangeForTarget(target, _spellInfo);
+
+
+ if (target && target != _caster)
+ {
+ if (range_type == SPELL_RANGE_MELEE)
+ {
+ // Because of lag, we can not check too strictly here.
+ if (!_caster->IsWithinMeleeRange(target, max_range))
+ return false;
+ }
+ else if (!_caster->IsWithinCombatRange(target, max_range))
+ return false;
+
+ if (range_type == SPELL_RANGE_RANGED)
+ {
+ if (_caster->IsWithinMeleeRange(target))
+ return false;
+ }
+ else if (min_range && _caster->IsWithinCombatRange(target, min_range)) // skip this check if min_range = 0
+ return false;
+ }
+
+ return true;
+}
+
+bool NonTankTargetSelector::operator()(Unit const* target) const
+{
+ return target != _source->getVictim();
+}
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 98f0e4bb1a4..bd6a9b37b5a 100755
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -97,6 +97,32 @@ struct DefaultTargetSelector : public std::unary_function<Unit* , bool>
}
};
+// Target selector for spell casts checking range, auras and attributes
+// TODO: Add more checks from Spell::CheckCast
+struct SpellTargetSelector : public std::unary_function<Unit*, bool>
+{
+ public:
+ SpellTargetSelector(Unit* caster, uint32 spellId);
+ bool operator()(Unit const* target) const;
+
+ private:
+ Unit const* _caster;
+ SpellInfo const* _spellInfo;
+};
+
+// Very simple target selector, will just skip main target
+// NOTE: When passing to UnitAI::SelectTarget remember to use 0 as position for random selection
+// because tank will not be in the temporary list
+struct NonTankTargetSelector : public std::unary_function<Unit*, bool>
+{
+ public:
+ explicit NonTankTargetSelector(Creature* source) : _source(source) { }
+ bool operator()(Unit const* target) const;
+
+ private:
+ Creature const* _source;
+};
+
class UnitAI
{
protected:
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 2de0759a0d4..26e3a79503d 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -5594,6 +5594,13 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
instance->DoCastSpellOnPlayers(65037); // Achievement criteria marker
break;
}
+ // Dark Hunger (The Lich King encounter)
+ case 69383:
+ {
+ basepoints0 = CalculatePctN(int32(damage), 50);
+ triggered_spell_id = 69384;
+ break;
+ }
}
break;
}
@@ -9240,7 +9247,7 @@ ReputationRank Unit::GetReactionTo(Unit const* target) const
if (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_FFA_PVP
&& target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_FFA_PVP)
return REP_HOSTILE;
-
+
if (selfPlayerOwner)
{
if (FactionTemplateEntry const* targetFactionTemplateEntry = target->getFactionTemplateEntry())
@@ -12416,7 +12423,7 @@ bool Unit::_IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell) co
&& target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_FFA_PVP)
return true;
- return (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_UNK1)
+ return (GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_UNK1)
|| (target->GetByteValue(UNIT_FIELD_BYTES_2, 1) & UNIT_BYTE2_FLAG_UNK1);
}
return true;
@@ -13479,7 +13486,7 @@ void Unit::ApplyDiminishingAura(DiminishingGroup group, bool apply)
}
}
-float Unit::GetSpellMaxRangeForTarget(Unit* target, SpellInfo const* spellInfo)
+float Unit::GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const
{
if (!spellInfo->RangeEntry)
return 0;
@@ -13488,7 +13495,7 @@ float Unit::GetSpellMaxRangeForTarget(Unit* target, SpellInfo const* spellInfo)
return spellInfo->GetMaxRange(!IsHostileTo(target));
}
-float Unit::GetSpellMinRangeForTarget(Unit* target, SpellInfo const* spellInfo)
+float Unit::GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const
{
if (!spellInfo->RangeEntry)
return 0;
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 6f2090dee9b..e0935ea3b86 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1255,8 +1255,8 @@ class Unit : public WorldObject
void ClearDiminishings() { m_Diminishing.clear(); }
// target dependent range checks
- float GetSpellMaxRangeForTarget(Unit* target, SpellInfo const* spellInfo);
- float GetSpellMinRangeForTarget(Unit* target, SpellInfo const* spellInfo);
+ float GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
+ float GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
virtual void Update(uint32 time);
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 8f8748cfdec..33d03999ad4 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -807,7 +807,7 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType())
{
- // add explicit object target or self to the target map
+ // add explicit object target or self to the target map
case EFFECT_IMPLICIT_TARGET_EXPLICIT:
// player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK
if (targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK))
@@ -839,7 +839,7 @@ void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex)
AddGOTarget(gObjTarget, 1 << effIndex);
}
break;
- // add self to the target map
+ // add self to the target map
case EFFECT_IMPLICIT_TARGET_CASTER:
if (targetMask & TARGET_FLAG_UNIT_MASK)
AddUnitTarget(m_caster, 1 << effIndex, false);