diff options
author | Shauren <shauren.trinity@gmail.com> | 2011-09-24 19:40:57 +0200 |
---|---|---|
committer | Shauren <shauren.trinity@gmail.com> | 2011-09-24 19:40:57 +0200 |
commit | da0229da8f6c22d71729bed54ab608b0b805112e (patch) | |
tree | 1af09c7385d0de22c50e18480e8b04bb17393bfb | |
parent | cd7060c65adfaafe22c67bce065e2358f158e932 (diff) |
Core/Scripts: Implemented 2 new target selectors, one specialized for spells, checking auras, range and attributes; and the other is a very simple non-tank selection what is sufficient for most cases
-rwxr-xr-x | src/server/game/AI/CoreAI/UnitAI.cpp | 46 | ||||
-rwxr-xr-x | src/server/game/AI/CoreAI/UnitAI.h | 26 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.cpp | 15 | ||||
-rwxr-xr-x | src/server/game/Entities/Unit/Unit.h | 4 | ||||
-rwxr-xr-x | src/server/game/Spells/Spell.cpp | 4 |
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); |