Core/Spells: rework part 5: GameObject casting
Closes #21330 Closes #18885 Ref #18752 (cherry picked from commit 45c5e1b9d63796d168339a44f63418f220cf2403)
This commit is contained in:
@@ -28,6 +28,7 @@ class Player;
|
||||
class Quest;
|
||||
class SpellInfo;
|
||||
class Unit;
|
||||
class WorldObject;
|
||||
enum class QuestGiverStatus : uint32;
|
||||
|
||||
class TC_GAME_API GameObjectAI
|
||||
@@ -73,8 +74,8 @@ class TC_GAME_API GameObjectAI
|
||||
// prevents achievement tracking if returning true
|
||||
virtual bool OnReportUse(Player* /*player*/) { return false; }
|
||||
|
||||
virtual void Destroyed(Player* /*player*/, uint32 /*eventId*/) { }
|
||||
virtual void Damaged(Player* /*player*/, uint32 /*eventId*/) { }
|
||||
virtual void Destroyed(WorldObject* /*attacker*/, uint32 /*eventId*/) { }
|
||||
virtual void Damaged(WorldObject* /*attacker*/, uint32 /*eventId*/) { }
|
||||
|
||||
virtual uint32 GetData(uint32 /*id*/) const { return 0; }
|
||||
virtual void SetData64(uint32 /*id*/, uint64 /*value*/) { }
|
||||
@@ -85,7 +86,14 @@ class TC_GAME_API GameObjectAI
|
||||
virtual void OnLootStateChanged(uint32 /*state*/, Unit* /*unit*/) { }
|
||||
virtual void OnStateChanged(uint32 /*state*/) { }
|
||||
virtual void EventInform(uint32 /*eventId*/) { }
|
||||
virtual void SpellHit(Unit* /*unit*/, SpellInfo const* /*spellInfo*/) { }
|
||||
|
||||
// Called when hit by a spell
|
||||
virtual void SpellHit(Unit* /*caster*/, SpellInfo const* /*spellInfo*/) { }
|
||||
virtual void SpellHit(GameObject* /*caster*/, SpellInfo const* /*spellInfo*/) { }
|
||||
|
||||
// Called when spell hits a target
|
||||
virtual void SpellHitTarget(Unit* /*target*/, SpellInfo const* /*spellInfo*/) { }
|
||||
virtual void SpellHitTarget(GameObject* /*target*/, SpellInfo const* /*spellInfo*/) { }
|
||||
};
|
||||
|
||||
class TC_GAME_API NullGameObjectAI : public GameObjectAI
|
||||
|
||||
@@ -113,10 +113,12 @@ class TC_GAME_API CreatureAI : public UnitAI
|
||||
virtual void JustUnregisteredAreaTrigger(AreaTrigger* /*areaTrigger*/) { }
|
||||
|
||||
// Called when hit by a spell
|
||||
virtual void SpellHit(Unit* /*caster*/, SpellInfo const* /*spell*/) { }
|
||||
virtual void SpellHit(Unit* /*caster*/, SpellInfo const* /*spellInfo*/) { }
|
||||
virtual void SpellHit(GameObject* /*caster*/, SpellInfo const* /*spellInfo*/) { }
|
||||
|
||||
// Called when spell hits a target
|
||||
virtual void SpellHitTarget(Unit* /*target*/, SpellInfo const* /*spell*/) { }
|
||||
virtual void SpellHitTarget(Unit* /*target*/, SpellInfo const* /*spellInfo*/) { }
|
||||
virtual void SpellHitTarget(GameObject* /*target*/, SpellInfo const* /*spellInfo*/) { }
|
||||
|
||||
virtual bool IsEscorted() const { return false; }
|
||||
|
||||
|
||||
@@ -142,33 +142,9 @@ struct TC_GAME_API ScriptedAI : public CreatureAI
|
||||
|
||||
void AttackStartNoMove(Unit* target);
|
||||
|
||||
// Called at any Damage from any attacker (before damage apply)
|
||||
void DamageTaken(Unit* /*attacker*/, uint32& /*damage*/) override { }
|
||||
|
||||
//Called at World update tick
|
||||
virtual void UpdateAI(uint32 diff) override;
|
||||
|
||||
//Called at creature death
|
||||
void JustDied(Unit* /*killer*/) override { }
|
||||
|
||||
//Called at creature killing another unit
|
||||
void KilledUnit(Unit* /*victim*/) override { }
|
||||
|
||||
// Called when the creature summon successfully other creature
|
||||
void JustSummoned(Creature* /*summon*/) override { }
|
||||
|
||||
// Called when a summoned creature is despawned
|
||||
void SummonedCreatureDespawn(Creature* /*summon*/) override { }
|
||||
|
||||
// Called when hit by a spell
|
||||
void SpellHit(Unit* /*caster*/, SpellInfo const* /*spell*/) override { }
|
||||
|
||||
// Called when spell hits a target
|
||||
void SpellHitTarget(Unit* /*target*/, SpellInfo const* /*spell*/) override { }
|
||||
|
||||
// Called when AI is temporarily replaced or put back when possess is applied or removed
|
||||
void OnPossess(bool /*apply*/) { }
|
||||
|
||||
// *************
|
||||
// Variables
|
||||
// *************
|
||||
@@ -180,12 +156,6 @@ struct TC_GAME_API ScriptedAI : public CreatureAI
|
||||
//Pure virtual functions
|
||||
// *************
|
||||
|
||||
//Called at creature reset either by death or evade
|
||||
void Reset() override { }
|
||||
|
||||
//Called at creature aggro either by MoveInLOS or Attack Start
|
||||
void JustEngagedWith(Unit* /*who*/) override { }
|
||||
|
||||
// Called before JustEngagedWith even before the creature is in combat.
|
||||
void AttackStart(Unit* /*target*/) override;
|
||||
|
||||
@@ -273,8 +243,8 @@ struct TC_GAME_API ScriptedAI : public CreatureAI
|
||||
// return true for 25 man or 25 man heroic mode
|
||||
bool Is25ManRaid() const { return _difficulty == DIFFICULTY_25_N || _difficulty == DIFFICULTY_25_HC; }
|
||||
|
||||
template<class T> inline
|
||||
const T& DUNGEON_MODE(const T& normal5, const T& heroic10) const
|
||||
template <class T>
|
||||
inline T const& DUNGEON_MODE(T const& normal5, T const& heroic10) const
|
||||
{
|
||||
switch (_difficulty)
|
||||
{
|
||||
@@ -289,8 +259,8 @@ struct TC_GAME_API ScriptedAI : public CreatureAI
|
||||
return heroic10;
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
const T& RAID_MODE(const T& normal10, const T& normal25) const
|
||||
template <class T>
|
||||
inline T const& RAID_MODE(T const& normal10, T const& normal25) const
|
||||
{
|
||||
switch (_difficulty)
|
||||
{
|
||||
@@ -305,8 +275,8 @@ struct TC_GAME_API ScriptedAI : public CreatureAI
|
||||
return normal25;
|
||||
}
|
||||
|
||||
template<class T> inline
|
||||
const T& RAID_MODE(const T& normal10, const T& normal25, const T& heroic10, const T& heroic25) const
|
||||
template <class T>
|
||||
inline T const& RAID_MODE(T const& normal10, T const& normal25, T const& heroic10, T const& heroic25) const
|
||||
{
|
||||
switch (_difficulty)
|
||||
{
|
||||
|
||||
@@ -1025,9 +1025,9 @@ void SmartGameObjectAI::QuestReward(Player* player, Quest const* quest, LootItem
|
||||
}
|
||||
|
||||
// Called when the gameobject is destroyed (destructible buildings only).
|
||||
void SmartGameObjectAI::Destroyed(Player* player, uint32 eventId)
|
||||
void SmartGameObjectAI::Destroyed(WorldObject* attacker, uint32 eventId)
|
||||
{
|
||||
GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, player, eventId, 0, false, nullptr, me);
|
||||
GetScript()->ProcessEventsFor(SMART_EVENT_DEATH, attacker ? attacker->ToUnit() : nullptr, eventId, 0, false, nullptr, me);
|
||||
}
|
||||
|
||||
void SmartGameObjectAI::SetData(uint32 id, uint32 value, Unit* invoker)
|
||||
|
||||
@@ -262,7 +262,7 @@ class TC_GAME_API SmartGameObjectAI : public GameObjectAI
|
||||
bool GossipSelectCode(Player* player, uint32 menuId, uint32 gossipListId, char const* code) override;
|
||||
void QuestAccept(Player* player, Quest const* quest) override;
|
||||
void QuestReward(Player* player, Quest const* quest, LootItemType type, uint32 opt) override;
|
||||
void Destroyed(Player* player, uint32 eventId) override;
|
||||
void Destroyed(WorldObject* attacker, uint32 eventId) override;
|
||||
void SetData(uint32 id, uint32 value, Unit* invoker);
|
||||
void SetData(uint32 id, uint32 value) override { SetData(id, value, nullptr); }
|
||||
void SetTimedActionList(SmartScriptHolder& e, uint32 entry, Unit* invoker);
|
||||
|
||||
@@ -296,7 +296,7 @@ bool CriteriaData::IsValid(Criteria const* criteria)
|
||||
}
|
||||
}
|
||||
|
||||
bool CriteriaData::Meets(uint32 criteriaId, Player const* source, Unit const* target, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/) const
|
||||
bool CriteriaData::Meets(uint32 criteriaId, Player const* source, WorldObject const* target, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/) const
|
||||
{
|
||||
switch (DataType)
|
||||
{
|
||||
@@ -325,11 +325,18 @@ bool CriteriaData::Meets(uint32 criteriaId, Player const* source, Unit const* ta
|
||||
case CRITERIA_DATA_TYPE_T_PLAYER_LESS_HEALTH:
|
||||
if (!target || target->GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
return !target->HealthAbovePct(Health.Percent);
|
||||
return !target->ToPlayer()->HealthAbovePct(Health.Percent);
|
||||
case CRITERIA_DATA_TYPE_S_AURA:
|
||||
return source->HasAuraEffect(Aura.SpellId, uint8(Aura.EffectIndex));
|
||||
case CRITERIA_DATA_TYPE_T_AURA:
|
||||
return target && target->HasAuraEffect(Aura.SpellId, uint8(Aura.EffectIndex));
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
Unit const* unitTarget = target->ToUnit();
|
||||
if (!unitTarget)
|
||||
return false;
|
||||
return unitTarget->HasAuraEffect(Aura.SpellId, uint8(Aura.EffectIndex));
|
||||
}
|
||||
case CRITERIA_DATA_TYPE_VALUE:
|
||||
return CompareValues(ComparisionType(Value.ComparisonType), miscValue1, Value.Value);
|
||||
case CRITERIA_DATA_TYPE_T_LEVEL:
|
||||
@@ -337,11 +344,21 @@ bool CriteriaData::Meets(uint32 criteriaId, Player const* source, Unit const* ta
|
||||
return false;
|
||||
return target->GetLevelForTarget(source) >= Level.Min;
|
||||
case CRITERIA_DATA_TYPE_T_GENDER:
|
||||
{
|
||||
if (!target)
|
||||
return false;
|
||||
return target->getGender() == Gender.Gender;
|
||||
Unit const* unitTarget = target->ToUnit();
|
||||
if (!unitTarget)
|
||||
return false;
|
||||
return unitTarget->getGender() == Gender.Gender;
|
||||
}
|
||||
case CRITERIA_DATA_TYPE_SCRIPT:
|
||||
return sScriptMgr->OnCriteriaCheck(ScriptId, const_cast<Player*>(source), const_cast<Unit*>(target));
|
||||
{
|
||||
Unit const* unitTarget = nullptr;
|
||||
if (target)
|
||||
unitTarget = target->ToUnit();
|
||||
return sScriptMgr->OnCriteriaCheck(ScriptId, const_cast<Player*>(source), const_cast<Unit*>(unitTarget));
|
||||
}
|
||||
case CRITERIA_DATA_TYPE_MAP_PLAYER_COUNT:
|
||||
return source->GetMap()->GetPlayersCountExceptGMs() <= MapPlayers.MaxCount;
|
||||
case CRITERIA_DATA_TYPE_T_TEAM:
|
||||
@@ -381,7 +398,11 @@ bool CriteriaData::Meets(uint32 criteriaId, Player const* source, Unit const* ta
|
||||
DataType, criteriaId, map->GetId());
|
||||
return false;
|
||||
}
|
||||
return instance->CheckAchievementCriteriaMeet(criteriaId, source, target, miscValue1);
|
||||
|
||||
Unit const* unitTarget = nullptr;
|
||||
if (target)
|
||||
unitTarget = target->ToUnit();
|
||||
return instance->CheckAchievementCriteriaMeet(criteriaId, source, unitTarget, miscValue1);
|
||||
}
|
||||
case CRITERIA_DATA_TYPE_S_EQUIPPED_ITEM:
|
||||
{
|
||||
@@ -415,7 +436,7 @@ bool CriteriaData::Meets(uint32 criteriaId, Player const* source, Unit const* ta
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CriteriaDataSet::Meets(Player const* source, Unit const* target, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/) const
|
||||
bool CriteriaDataSet::Meets(Player const* source, WorldObject const* target, uint32 miscValue1 /*= 0*/, uint32 miscValue2 /*= 0*/) const
|
||||
{
|
||||
for (CriteriaData const& data : _storage)
|
||||
if (!data.Meets(_criteriaId, source, target, miscValue1, miscValue2))
|
||||
@@ -439,7 +460,7 @@ void CriteriaHandler::Reset()
|
||||
/**
|
||||
* this function will be called whenever the user might have done a criteria relevant action
|
||||
*/
|
||||
void CriteriaHandler::UpdateCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, Unit const* unit /*= nullptr*/, Player* referencePlayer /*= nullptr*/)
|
||||
void CriteriaHandler::UpdateCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, WorldObject const* ref /*= nullptr*/, Player* referencePlayer /*= nullptr*/)
|
||||
{
|
||||
if (type >= CRITERIA_TYPE_TOTAL)
|
||||
{
|
||||
@@ -468,12 +489,12 @@ void CriteriaHandler::UpdateCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0
|
||||
for (Criteria const* criteria : criteriaList)
|
||||
{
|
||||
CriteriaTreeList const* trees = sCriteriaMgr->GetCriteriaTreesByCriteria(criteria->ID);
|
||||
if (!CanUpdateCriteria(criteria, trees, miscValue1, miscValue2, miscValue3, unit, referencePlayer))
|
||||
if (!CanUpdateCriteria(criteria, trees, miscValue1, miscValue2, miscValue3, ref, referencePlayer))
|
||||
continue;
|
||||
|
||||
// requirements not found in the dbc
|
||||
if (CriteriaDataSet const* data = sCriteriaMgr->GetCriteriaDataSet(criteria))
|
||||
if (!data->Meets(referencePlayer, unit, uint32(miscValue1), uint32(miscValue2)))
|
||||
if (!data->Meets(referencePlayer, ref, uint32(miscValue1), uint32(miscValue2)))
|
||||
continue;
|
||||
|
||||
switch (type)
|
||||
@@ -1253,7 +1274,7 @@ bool CriteriaHandler::IsCompletedCriteria(Criteria const* criteria, uint64 requi
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CriteriaHandler::CanUpdateCriteria(Criteria const* criteria, CriteriaTreeList const* trees, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer)
|
||||
bool CriteriaHandler::CanUpdateCriteria(Criteria const* criteria, CriteriaTreeList const* trees, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, WorldObject const* ref, Player* referencePlayer)
|
||||
{
|
||||
if (DisableMgr::IsDisabledFor(DISABLE_TYPE_CRITERIA, criteria->ID, nullptr))
|
||||
{
|
||||
@@ -1274,13 +1295,13 @@ bool CriteriaHandler::CanUpdateCriteria(Criteria const* criteria, CriteriaTreeLi
|
||||
if (!treeRequirementPassed)
|
||||
return false;
|
||||
|
||||
if (!RequirementsSatisfied(criteria, miscValue1, miscValue2, miscValue3, unit, referencePlayer))
|
||||
if (!RequirementsSatisfied(criteria, miscValue1, miscValue2, miscValue3, ref, referencePlayer))
|
||||
{
|
||||
TC_LOG_TRACE("criteria", "CriteriaHandler::CanUpdateCriteria: (Id: %u Type %s) Requirements not satisfied", criteria->ID, CriteriaMgr::GetCriteriaTypeString(criteria->Entry->Type));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (criteria->Modifier && !ModifierTreeSatisfied(criteria->Modifier, miscValue1, miscValue2, unit, referencePlayer))
|
||||
if (criteria->Modifier && !ModifierTreeSatisfied(criteria->Modifier, miscValue1, miscValue2, ref, referencePlayer))
|
||||
{
|
||||
TC_LOG_TRACE("criteria", "CriteriaHandler::CanUpdateCriteria: (Id: %u Type %s) Requirements have not been satisfied", criteria->ID, CriteriaMgr::GetCriteriaTypeString(criteria->Entry->Type));
|
||||
return false;
|
||||
@@ -1317,7 +1338,7 @@ bool CriteriaHandler::ConditionsSatisfied(Criteria const* criteria, Player* refe
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer) const
|
||||
bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, WorldObject const* ref, Player* referencePlayer) const
|
||||
{
|
||||
switch (CriteriaTypes(criteria->Entry->Type))
|
||||
{
|
||||
@@ -1428,7 +1449,7 @@ bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 mis
|
||||
break;
|
||||
}
|
||||
case CRITERIA_TYPE_KILLED_BY_PLAYER:
|
||||
if (!miscValue1 || !unit || unit->GetTypeId() != TYPEID_PLAYER)
|
||||
if (!miscValue1 || !ref || ref->GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
break;
|
||||
case CRITERIA_TYPE_DEATHS_FROM:
|
||||
@@ -1451,7 +1472,7 @@ bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 mis
|
||||
}
|
||||
|
||||
if (CriteriaDataSet const* data = sCriteriaMgr->GetCriteriaDataSet(criteria))
|
||||
if (!data->Meets(referencePlayer, unit))
|
||||
if (!data->Meets(referencePlayer, ref))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@@ -1554,7 +1575,7 @@ bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 mis
|
||||
return false;
|
||||
|
||||
// map specific case (BG in fact) expected player targeted damage/heal
|
||||
if (!unit || unit->GetTypeId() != TYPEID_PLAYER)
|
||||
if (!ref || ref->GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
@@ -1618,24 +1639,24 @@ bool CriteriaHandler::RequirementsSatisfied(Criteria const* criteria, uint64 mis
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CriteriaHandler::ModifierTreeSatisfied(ModifierTreeNode const* tree, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const
|
||||
bool CriteriaHandler::ModifierTreeSatisfied(ModifierTreeNode const* tree, uint64 miscValue1, uint64 miscValue2, WorldObject const* ref, Player* referencePlayer) const
|
||||
{
|
||||
switch (ModifierTreeOperator(tree->Entry->Operator))
|
||||
{
|
||||
case ModifierTreeOperator::SingleTrue:
|
||||
return tree->Entry->Type && ModifierSatisfied(tree->Entry, miscValue1, miscValue2, unit, referencePlayer);
|
||||
return tree->Entry->Type && ModifierSatisfied(tree->Entry, miscValue1, miscValue2, ref, referencePlayer);
|
||||
case ModifierTreeOperator::SingleFalse:
|
||||
return tree->Entry->Type && !ModifierSatisfied(tree->Entry, miscValue1, miscValue2, unit, referencePlayer);
|
||||
return tree->Entry->Type && !ModifierSatisfied(tree->Entry, miscValue1, miscValue2, ref, referencePlayer);
|
||||
case ModifierTreeOperator::All:
|
||||
for (ModifierTreeNode const* node : tree->Children)
|
||||
if (!ModifierTreeSatisfied(node, miscValue1, miscValue2, unit, referencePlayer))
|
||||
if (!ModifierTreeSatisfied(node, miscValue1, miscValue2, ref, referencePlayer))
|
||||
return false;
|
||||
return true;
|
||||
case ModifierTreeOperator::Some:
|
||||
{
|
||||
int8 requiredAmount = std::max<int8>(tree->Entry->Amount, 1);
|
||||
for (ModifierTreeNode const* node : tree->Children)
|
||||
if (ModifierTreeSatisfied(node, miscValue1, miscValue2, unit, referencePlayer))
|
||||
if (ModifierTreeSatisfied(node, miscValue1, miscValue2, ref, referencePlayer))
|
||||
if (!--requiredAmount)
|
||||
return true;
|
||||
|
||||
@@ -1648,7 +1669,7 @@ bool CriteriaHandler::ModifierTreeSatisfied(ModifierTreeNode const* tree, uint64
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const
|
||||
bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint64 miscValue1, uint64 miscValue2, WorldObject const* ref, Player* referencePlayer) const
|
||||
{
|
||||
uint32 reqValue = modifier->Asset;
|
||||
uint32 secondaryAsset = modifier->SecondaryAsset;
|
||||
@@ -1679,19 +1700,19 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
break;
|
||||
}
|
||||
case ModifierTreeType::TargetCreatureId: // 4
|
||||
if (!unit || unit->GetEntry() != reqValue)
|
||||
if (!ref || ref->GetEntry() != reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetIsPlayer: // 5
|
||||
if (!unit || unit->GetTypeId() != TYPEID_PLAYER)
|
||||
if (!ref || ref->GetTypeId() != TYPEID_PLAYER)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetIsDead: // 6
|
||||
if (!unit || unit->IsAlive())
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->IsAlive())
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetIsOppositeFaction: // 7
|
||||
if (!unit || !referencePlayer->IsHostileTo(unit))
|
||||
if (!ref || !referencePlayer->IsHostileTo(ref))
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerHasAura: // 8
|
||||
@@ -1703,15 +1724,15 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetHasAura: // 10
|
||||
if (!unit || !unit->HasAura(reqValue))
|
||||
if (!ref || !ref->IsUnit() || !ref->ToUnit()->HasAura(reqValue))
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetHasAuraEffect: // 11
|
||||
if (!unit || !unit->HasAuraType(AuraType(reqValue)))
|
||||
if (!ref || !ref->IsUnit() || !ref->ToUnit()->HasAuraType(AuraType(reqValue)))
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetHasAuraState: // 12
|
||||
if (!unit || !unit->HasAuraState(AuraStateType(reqValue)))
|
||||
if (!ref || !ref->IsUnit() || !ref->ToUnit()->HasAuraState(AuraStateType(reqValue)))
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerHasAuraState: // 13
|
||||
@@ -1748,10 +1769,10 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
}
|
||||
case ModifierTreeType::TargetIsInArea: // 18
|
||||
{
|
||||
if (!unit)
|
||||
if (!ref)
|
||||
return false;
|
||||
uint32 zoneId, areaId;
|
||||
unit->GetZoneAndAreaId(zoneId, areaId);
|
||||
ref->GetZoneAndAreaId(zoneId, areaId);
|
||||
if (zoneId != reqValue && areaId != reqValue)
|
||||
return false;
|
||||
break;
|
||||
@@ -1768,15 +1789,15 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
break;
|
||||
}
|
||||
case ModifierTreeType::PlayerToTargetLevelDeltaGreaterThan: // 21
|
||||
if (!unit || referencePlayer->getLevel() < unit->getLevel() + reqValue)
|
||||
if (!ref || !ref->IsUnit() || referencePlayer->getLevel() < ref->ToUnit()->getLevel() + reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetToPlayerLevelDeltaGreaterThan: // 22
|
||||
if (!unit || referencePlayer->getLevel() + reqValue < unit->getLevel())
|
||||
if (!ref || !ref->IsUnit() || referencePlayer->getLevel() + reqValue < ref->ToUnit()->getLevel())
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerLevelEqualTargetLevel: // 23
|
||||
if (!unit || referencePlayer->getLevel() != unit->getLevel())
|
||||
if (!ref || !ref->IsUnit() || referencePlayer->getLevel() != ref->ToUnit()->getLevel())
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerInArenaWithTeamSize: // 24
|
||||
@@ -1795,11 +1816,11 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetRace: // 27
|
||||
if (!unit || unit->GetTypeId() != TYPEID_PLAYER || unit->getRace() != reqValue)
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->getRace() != reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetClass: // 28
|
||||
if (!unit || unit->GetTypeId() != TYPEID_PLAYER || unit->getClass() != reqValue)
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->getClass() != reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::LessThanTappers: // 29
|
||||
@@ -1808,17 +1829,17 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
break;
|
||||
case ModifierTreeType::CreatureType: // 30
|
||||
{
|
||||
if (!unit)
|
||||
if (!ref)
|
||||
return false;
|
||||
if (unit->GetTypeId() != TYPEID_UNIT || unit->GetCreatureType() != reqValue)
|
||||
if (!ref->IsUnit() || ref->ToUnit()->GetCreatureType() != reqValue)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
case ModifierTreeType::CreatureFamily: // 31
|
||||
{
|
||||
if (!unit)
|
||||
if (!ref)
|
||||
return false;
|
||||
if (unit->GetTypeId() != TYPEID_UNIT || unit->ToCreature()->GetCreatureTemplate()->family != CreatureFamily(reqValue))
|
||||
if (!ref->IsCreature() || ref->ToCreature()->GetCreatureTemplate()->family != CreatureFamily(reqValue))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@@ -1856,7 +1877,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetLevelEqual: // 40
|
||||
if (!unit || unit->GetLevelForTarget(referencePlayer) != reqValue)
|
||||
if (!ref || ref->GetLevelForTarget(referencePlayer) != reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerIsInZone: // 41
|
||||
@@ -1871,9 +1892,9 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
}
|
||||
case ModifierTreeType::TargetIsInZone: // 42
|
||||
{
|
||||
if (!unit)
|
||||
if (!ref)
|
||||
return false;
|
||||
uint32 zoneId = unit->GetAreaId();
|
||||
uint32 zoneId = ref->GetAreaId();
|
||||
if (AreaTableEntry const* areaEntry = sAreaTableStore.LookupEntry(zoneId))
|
||||
if (areaEntry->Flags[0] & AREA_FLAG_UNK9)
|
||||
zoneId = areaEntry->ParentAreaID;
|
||||
@@ -1894,15 +1915,15 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetHealthBelowPercent: // 46
|
||||
if (!unit || unit->GetHealthPct() > float(reqValue))
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->GetHealthPct() > float(reqValue))
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetHealthAbovePercent: // 47
|
||||
if (!unit || unit->GetHealthPct() < float(reqValue))
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->GetHealthPct() < float(reqValue))
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetHealthEqualsPercent: // 48
|
||||
if (!unit || unit->GetHealthPct() != float(reqValue))
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->GetHealthPct() != float(reqValue))
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerHealthBelowValue: // 49
|
||||
@@ -1918,24 +1939,24 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetHealthBelowValue: // 52
|
||||
if (!unit || unit->GetHealth() > reqValue)
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->GetHealth() > reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetHealthAboveValue: // 53
|
||||
if (!unit || unit->GetHealth() < reqValue)
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->GetHealth() < reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetHealthEqualsValue: // 54
|
||||
if (!unit || unit->GetHealth() != reqValue)
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->GetHealth() != reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetIsPlayerAndMeetsCondition: // 55
|
||||
{
|
||||
if (!unit || !unit->IsPlayer())
|
||||
if (!ref || !ref->IsPlayer())
|
||||
return false;
|
||||
|
||||
PlayerConditionEntry const* playerCondition = sPlayerConditionStore.LookupEntry(reqValue);
|
||||
if (!playerCondition || !ConditionMgr::IsPlayerMeetingCondition(unit->ToPlayer(), playerCondition))
|
||||
if (!playerCondition || !ConditionMgr::IsPlayerMeetingCondition(ref->ToPlayer(), playerCondition))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@@ -1995,7 +2016,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetLevelEqualOrGreaterThan: // 70
|
||||
if (!unit || unit->getLevel() < reqValue)
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->getLevel() < reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerLevelEqualOrLessThan: // 71
|
||||
@@ -2003,12 +2024,12 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetLevelEqualOrLessThan: // 72
|
||||
if (!unit || unit->getLevel() > reqValue)
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->getLevel() > reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::ModifierTree: // 73
|
||||
if (ModifierTreeNode const* nextModifierTree = sCriteriaMgr->GetModifierTree(reqValue))
|
||||
return ModifierTreeSatisfied(nextModifierTree, miscValue1, miscValue2, unit, referencePlayer);
|
||||
return ModifierTreeSatisfied(nextModifierTree, miscValue1, miscValue2, ref, referencePlayer);
|
||||
return false;
|
||||
case ModifierTreeType::PlayerScenario: // 74
|
||||
{
|
||||
@@ -2288,9 +2309,12 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
break;
|
||||
case ModifierTreeType::TargetThreatListSizeLessThan: // 120
|
||||
{
|
||||
if (!unit || !unit->CanHaveThreatList())
|
||||
if (!ref)
|
||||
return false;
|
||||
if (unit->GetThreatManager().GetThreatListSize() >= reqValue)
|
||||
Unit const* unitRef = ref->ToUnit();
|
||||
if (!unitRef || !unitRef->CanHaveThreatList())
|
||||
return false;
|
||||
if (unitRef->GetThreatManager().GetThreatListSize() >= reqValue)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@@ -3301,9 +3325,9 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
}
|
||||
case ModifierTreeType::TargetVisibleRace: // 253
|
||||
{
|
||||
if (!unit)
|
||||
if (!ref || !ref->IsUnit())
|
||||
return false;
|
||||
CreatureDisplayInfoEntry const* creatureDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(unit->GetDisplayId());
|
||||
CreatureDisplayInfoEntry const* creatureDisplayInfo = sCreatureDisplayInfoStore.LookupEntry(ref->ToUnit()->GetDisplayId());
|
||||
if (!creatureDisplayInfo)
|
||||
return false;
|
||||
CreatureDisplayInfoExtraEntry const* creatureDisplayInfoExtra = sCreatureDisplayInfoExtraStore.LookupEntry(creatureDisplayInfo->ExtendedDisplayInfoID);
|
||||
@@ -3338,7 +3362,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetAuraStackCountEqual: // 256
|
||||
if (!unit || unit->GetAuraCount(secondaryAsset) != reqValue)
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->GetAuraCount(secondaryAsset) != reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerAuraStackCountEqualOrGreaterThan: // 257
|
||||
@@ -3346,7 +3370,7 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetAuraStackCountEqualOrGreaterThan: // 258
|
||||
if (!unit || unit->GetAuraCount(secondaryAsset) < reqValue)
|
||||
if (!ref || !ref->IsUnit() || ref->ToUnit()->GetAuraCount(secondaryAsset) < reqValue)
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerHasAzeriteEssenceRankLessThan: // 259
|
||||
@@ -3429,9 +3453,9 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
}
|
||||
case ModifierTreeType::TargetLevelWithinContentTuning: // 269
|
||||
{
|
||||
if (!unit)
|
||||
if (!ref || !ref->IsUnit())
|
||||
return false;
|
||||
uint8 level = unit->getLevel();
|
||||
uint8 level = ref->ToUnit()->getLevel();
|
||||
if (Optional<ContentTuningLevels> levels = sDB2Manager.GetContentTuningData(reqValue, 0))
|
||||
{
|
||||
if (secondaryAsset)
|
||||
@@ -3458,9 +3482,9 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
}
|
||||
case ModifierTreeType::TargetLevelWithinOrAboveContentTuning: // 273
|
||||
{
|
||||
if (!unit)
|
||||
if (!ref || !ref->IsUnit())
|
||||
return false;
|
||||
uint8 level = unit->getLevel();
|
||||
uint8 level = ref->ToUnit()->getLevel();
|
||||
if (Optional<ContentTuningLevels> levels = sDB2Manager.GetContentTuningData(reqValue, 0))
|
||||
return secondaryAsset ? level >= levels->MinLevelWithDelta : level >= levels->MinLevel;
|
||||
return false;
|
||||
@@ -3570,10 +3594,10 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
}
|
||||
case ModifierTreeType::TargetIsInAreaGroup: // 299
|
||||
{
|
||||
if (!unit)
|
||||
if (!ref)
|
||||
return false;
|
||||
std::vector<uint32> areas = sDB2Manager.GetAreasForGroup(reqValue);
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(unit->GetAreaId()))
|
||||
if (AreaTableEntry const* area = sAreaTableStore.LookupEntry(ref->GetAreaId()))
|
||||
for (uint32 areaInGroup : areas)
|
||||
if (areaInGroup == area->ID || areaInGroup == area->ParentAreaID)
|
||||
return true;
|
||||
@@ -3660,9 +3684,9 @@ bool CriteriaHandler::ModifierSatisfied(ModifierTreeEntry const* modifier, uint6
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::TargetCovenant: // 314
|
||||
if (!unit || !unit->IsPlayer())
|
||||
if (!ref || !ref->IsPlayer())
|
||||
return false;
|
||||
if (unit->ToPlayer()->m_playerData->CovenantID != int32(reqValue))
|
||||
if (ref->ToPlayer()->m_playerData->CovenantID != int32(reqValue))
|
||||
return false;
|
||||
break;
|
||||
case ModifierTreeType::PlayerHasTBCCollectorsEdition: // 315
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#include <ctime>
|
||||
|
||||
class Player;
|
||||
class Unit;
|
||||
class WorldObject;
|
||||
class WorldPacket;
|
||||
struct AchievementEntry;
|
||||
struct CriteriaEntry;
|
||||
@@ -239,14 +239,14 @@ struct CriteriaData
|
||||
}
|
||||
|
||||
bool IsValid(Criteria const* criteria);
|
||||
bool Meets(uint32 criteriaId, Player const* source, Unit const* target, uint32 miscValue1 = 0, uint32 miscValue2 = 0) const;
|
||||
bool Meets(uint32 criteriaId, Player const* source, WorldObject const* target, uint32 miscValue1 = 0, uint32 miscValue2 = 0) const;
|
||||
};
|
||||
|
||||
struct CriteriaDataSet
|
||||
{
|
||||
CriteriaDataSet() : _criteriaId(0) { }
|
||||
void Add(CriteriaData const& data) { _storage.push_back(data); }
|
||||
bool Meets(Player const* source, Unit const* target, uint32 miscValue1 = 0, uint32 miscValue2 = 0) const;
|
||||
bool Meets(Player const* source, WorldObject const* target, uint32 miscValue1 = 0, uint32 miscValue2 = 0) const;
|
||||
void SetCriteriaId(uint32 id) { _criteriaId = id; }
|
||||
private:
|
||||
uint32 _criteriaId;
|
||||
@@ -271,7 +271,7 @@ public:
|
||||
|
||||
virtual void Reset();
|
||||
|
||||
void UpdateCriteria(CriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, Unit const* unit = nullptr, Player* referencePlayer = nullptr);
|
||||
void UpdateCriteria(CriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, WorldObject const* ref = nullptr, Player* referencePlayer = nullptr);
|
||||
|
||||
virtual void SendAllData(Player const* receiver) const = 0;
|
||||
|
||||
@@ -294,15 +294,15 @@ protected:
|
||||
virtual void AfterCriteriaTreeUpdate(CriteriaTree const* /*tree*/, Player* /*referencePlayer*/) { }
|
||||
|
||||
bool IsCompletedCriteria(Criteria const* criteria, uint64 requiredAmount);
|
||||
bool CanUpdateCriteria(Criteria const* criteria, CriteriaTreeList const* trees, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer);
|
||||
bool CanUpdateCriteria(Criteria const* criteria, CriteriaTreeList const* trees, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, WorldObject const* ref, Player* referencePlayer);
|
||||
|
||||
virtual void SendPacket(WorldPacket const* data) const = 0;
|
||||
|
||||
bool ConditionsSatisfied(Criteria const* criteria, Player* referencePlayer) const;
|
||||
bool RequirementsSatisfied(Criteria const* criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit const* unit, Player* referencePlayer) const;
|
||||
bool RequirementsSatisfied(Criteria const* criteria, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, WorldObject const* ref, Player* referencePlayer) const;
|
||||
virtual bool RequiredAchievementSatisfied(uint32 /*achievementId*/) const { return false; }
|
||||
bool ModifierTreeSatisfied(ModifierTreeNode const* parent, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const;
|
||||
bool ModifierSatisfied(ModifierTreeEntry const* modifier, uint64 miscValue1, uint64 miscValue2, Unit const* unit, Player* referencePlayer) const;
|
||||
bool ModifierTreeSatisfied(ModifierTreeNode const* parent, uint64 miscValue1, uint64 miscValue2, WorldObject const* ref, Player* referencePlayer) const;
|
||||
bool ModifierSatisfied(ModifierTreeEntry const* modifier, uint64 miscValue1, uint64 miscValue2, WorldObject const* ref, Player* referencePlayer) const;
|
||||
|
||||
virtual std::string GetOwnerInfo() const = 0;
|
||||
virtual CriteriaList const& GetCriteriaByType(CriteriaTypes type, uint32 asset) const = 0;
|
||||
|
||||
@@ -272,7 +272,7 @@ void CheckQuestDisables()
|
||||
TC_LOG_INFO("server.loading", ">> Checked " SZFMTD " quest disables in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
|
||||
bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags)
|
||||
bool IsDisabledFor(DisableType type, uint32 entry, WorldObject const* ref, uint8 flags /*= 0*/)
|
||||
{
|
||||
ASSERT(type < MAX_DISABLE_TYPES);
|
||||
if (m_DisableMap[type].empty())
|
||||
@@ -287,15 +287,16 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
|
||||
case DISABLE_TYPE_SPELL:
|
||||
{
|
||||
uint8 spellFlags = itr->second.flags;
|
||||
if (unit)
|
||||
if (ref)
|
||||
{
|
||||
if ((spellFlags & SPELL_DISABLE_PLAYER && unit->GetTypeId() == TYPEID_PLAYER) ||
|
||||
(unit->GetTypeId() == TYPEID_UNIT && ((unit->IsPet() && spellFlags & SPELL_DISABLE_PET) || spellFlags & SPELL_DISABLE_CREATURE)))
|
||||
if ((ref->GetTypeId() == TYPEID_PLAYER && (spellFlags & SPELL_DISABLE_PLAYER)) ||
|
||||
(ref->GetTypeId() == TYPEID_UNIT && ((spellFlags & SPELL_DISABLE_CREATURE) || (ref->ToUnit()->IsPet() && (spellFlags & SPELL_DISABLE_PET)))) ||
|
||||
(ref->GetTypeId() == TYPEID_GAMEOBJECT && (spellFlags & SPELL_DISABLE_GAMEOBJECT)))
|
||||
{
|
||||
if (spellFlags & SPELL_DISABLE_MAP)
|
||||
{
|
||||
std::unordered_set<uint32> const& mapIds = itr->second.params[0];
|
||||
if (mapIds.find(unit->GetMapId()) != mapIds.end())
|
||||
if (mapIds.find(ref->GetMapId()) != mapIds.end())
|
||||
return true; // Spell is disabled on current map
|
||||
|
||||
if (!(spellFlags & SPELL_DISABLE_AREA))
|
||||
@@ -307,7 +308,7 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
|
||||
if (spellFlags & SPELL_DISABLE_AREA)
|
||||
{
|
||||
std::unordered_set<uint32> const& areaIds = itr->second.params[1];
|
||||
if (areaIds.find(unit->GetAreaId()) != areaIds.end())
|
||||
if (areaIds.find(ref->GetAreaId()) != areaIds.end())
|
||||
return true; // Spell is disabled in this area
|
||||
return false; // Spell is disabled in another area, but not this one, return false
|
||||
}
|
||||
@@ -326,7 +327,7 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
|
||||
}
|
||||
case DISABLE_TYPE_MAP:
|
||||
case DISABLE_TYPE_LFG_MAP:
|
||||
if (Player const* player = unit->ToPlayer())
|
||||
if (Player const* player = ref->ToPlayer())
|
||||
{
|
||||
MapEntry const* mapEntry = sMapStore.LookupEntry(entry);
|
||||
if (mapEntry->IsDungeon())
|
||||
@@ -353,9 +354,9 @@ bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags
|
||||
}
|
||||
return false;
|
||||
case DISABLE_TYPE_QUEST:
|
||||
if (!unit)
|
||||
if (!ref)
|
||||
return true;
|
||||
if (Player const* player = unit->ToPlayer())
|
||||
if (Player const* player = ref->ToPlayer())
|
||||
if (player->IsGameMaster())
|
||||
return false;
|
||||
return true;
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
#include "Define.h"
|
||||
|
||||
class Unit;
|
||||
class WorldObject;
|
||||
|
||||
enum DisableType
|
||||
{
|
||||
@@ -39,16 +39,17 @@ enum DisableType
|
||||
|
||||
enum SpellDisableTypes
|
||||
{
|
||||
SPELL_DISABLE_PLAYER = 0x1,
|
||||
SPELL_DISABLE_CREATURE = 0x2,
|
||||
SPELL_DISABLE_PET = 0x4,
|
||||
SPELL_DISABLE_DEPRECATED_SPELL = 0x8,
|
||||
SPELL_DISABLE_PLAYER = 0x01,
|
||||
SPELL_DISABLE_CREATURE = 0x02,
|
||||
SPELL_DISABLE_PET = 0x04,
|
||||
SPELL_DISABLE_DEPRECATED_SPELL = 0x08,
|
||||
SPELL_DISABLE_MAP = 0x10,
|
||||
SPELL_DISABLE_AREA = 0x20,
|
||||
SPELL_DISABLE_LOS = 0x40,
|
||||
SPELL_DISABLE_GAMEOBJECT = 0x80,
|
||||
MAX_SPELL_DISABLE_TYPE = ( SPELL_DISABLE_PLAYER | SPELL_DISABLE_CREATURE | SPELL_DISABLE_PET |
|
||||
SPELL_DISABLE_DEPRECATED_SPELL | SPELL_DISABLE_MAP | SPELL_DISABLE_AREA |
|
||||
SPELL_DISABLE_LOS)
|
||||
SPELL_DISABLE_LOS | SPELL_DISABLE_GAMEOBJECT )
|
||||
};
|
||||
|
||||
enum MMapDisableTypes
|
||||
@@ -59,7 +60,7 @@ enum MMapDisableTypes
|
||||
namespace DisableMgr
|
||||
{
|
||||
TC_GAME_API void LoadDisables();
|
||||
TC_GAME_API bool IsDisabledFor(DisableType type, uint32 entry, Unit const* unit, uint8 flags = 0);
|
||||
TC_GAME_API bool IsDisabledFor(DisableType type, uint32 entry, WorldObject const* ref, uint8 flags = 0);
|
||||
TC_GAME_API void CheckQuestDisables();
|
||||
TC_GAME_API bool IsVMAPDisabledFor(uint32 entry, uint8 flags);
|
||||
TC_GAME_API bool IsPathfindingEnabled(uint32 mapId);
|
||||
|
||||
@@ -500,6 +500,14 @@ Unit* AreaTrigger::GetTarget() const
|
||||
return ObjectAccessor::GetUnit(*this, _targetGuid);
|
||||
}
|
||||
|
||||
uint32 AreaTrigger::GetFaction() const
|
||||
{
|
||||
if (Unit const* caster = GetCaster())
|
||||
return caster->GetFaction();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void AreaTrigger::UpdatePolygonOrientation()
|
||||
{
|
||||
float newOrientation = GetOrientation();
|
||||
|
||||
@@ -92,10 +92,13 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge
|
||||
AreaTriggerTemplate const* GetTemplate() const;
|
||||
uint32 GetScriptId() const;
|
||||
|
||||
ObjectGuid GetOwnerGUID() const override { return GetCasterGuid(); }
|
||||
ObjectGuid const& GetCasterGuid() const { return m_areaTriggerData->Caster; }
|
||||
Unit* GetCaster() const;
|
||||
Unit* GetTarget() const;
|
||||
|
||||
uint32 GetFaction() const override;
|
||||
|
||||
Position const& GetRollPitchYaw() const { return _rollPitchYaw; }
|
||||
Position const& GetTargetRollPitchYaw() const { return _targetRollPitchYaw; }
|
||||
void InitSplineOffsets(std::vector<Position> const& offsets, uint32 timeToTarget);
|
||||
@@ -112,7 +115,6 @@ class TC_GAME_API AreaTrigger : public WorldObject, public GridObject<AreaTrigge
|
||||
|
||||
UF::UpdateField<UF::AreaTriggerData, 0, TYPEID_AREATRIGGER> m_areaTriggerData;
|
||||
|
||||
|
||||
protected:
|
||||
void _UpdateDuration(int32 newDuration);
|
||||
float GetProgress() const;
|
||||
|
||||
@@ -56,6 +56,8 @@ class TC_GAME_API Conversation : public WorldObject, public GridObject<Conversat
|
||||
void AddParticipant(ObjectGuid const& participantGuid);
|
||||
|
||||
ObjectGuid const& GetCreatorGuid() const { return _creatorGuid; }
|
||||
ObjectGuid GetOwnerGUID() const override { return GetCreatorGuid(); }
|
||||
uint32 GetFaction() const override { return 0; }
|
||||
|
||||
float GetStationaryX() const override { return _stationaryPosition.GetPositionX(); }
|
||||
float GetStationaryY() const override { return _stationaryPosition.GetPositionY(); }
|
||||
|
||||
@@ -77,7 +77,7 @@ class TC_GAME_API Corpse : public WorldObject, public GridObject<Corpse>
|
||||
void AddCorpseDynamicFlag(CorpseDynFlags dynamicFlags) { SetUpdateFieldFlagValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::DynamicFlags), dynamicFlags); }
|
||||
void RemoveCorpseDynamicFlag(CorpseDynFlags dynamicFlags) { RemoveUpdateFieldFlagValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::DynamicFlags), dynamicFlags); }
|
||||
void SetCorpseDynamicFlags(CorpseDynFlags dynamicFlags) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::DynamicFlags), dynamicFlags); }
|
||||
ObjectGuid GetOwnerGUID() const { return m_corpseData->Owner; }
|
||||
ObjectGuid GetOwnerGUID() const override { return m_corpseData->Owner; }
|
||||
void SetOwnerGUID(ObjectGuid owner) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::Owner), owner); }
|
||||
void SetPartyGUID(ObjectGuid partyGuid) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::PartyGUID), partyGuid); }
|
||||
void SetGuildGUID(ObjectGuid guildGuid) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::GuildGUID), guildGuid); }
|
||||
@@ -87,6 +87,8 @@ class TC_GAME_API Corpse : public WorldObject, public GridObject<Corpse>
|
||||
void SetSex(uint8 sex) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::Sex), sex); }
|
||||
void SetFlags(uint32 flags) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::Flags), flags); }
|
||||
void SetFactionTemplate(int32 factionTemplate) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::FactionTemplate), factionTemplate); }
|
||||
uint32 GetFaction() const override { return m_corpseData->FactionTemplate; }
|
||||
void SetFaction(uint32 faction) override { SetFactionTemplate(faction); }
|
||||
void SetItem(uint32 slot, uint32 item) { SetUpdateFieldValue(m_values.ModifyValue(&Corpse::m_corpseData).ModifyValue(&UF::CorpseData::Items, slot), item); }
|
||||
|
||||
template<typename Iter>
|
||||
|
||||
@@ -2355,7 +2355,7 @@ void Creature::LoadTemplateImmunities()
|
||||
}
|
||||
}
|
||||
|
||||
bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo, Unit* caster) const
|
||||
bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo, WorldObject const* caster) const
|
||||
{
|
||||
if (!spellInfo)
|
||||
return false;
|
||||
@@ -2379,7 +2379,7 @@ bool Creature::IsImmunedToSpell(SpellInfo const* spellInfo, Unit* caster) const
|
||||
return Unit::IsImmunedToSpell(spellInfo, caster);
|
||||
}
|
||||
|
||||
bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const
|
||||
bool Creature::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, WorldObject const* caster) const
|
||||
{
|
||||
SpellEffectInfo const* effect = spellInfo->GetEffect(index);
|
||||
if (!effect)
|
||||
|
||||
@@ -127,8 +127,8 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
||||
bool CanResetTalents(Player* player) const;
|
||||
bool CanCreatureAttack(Unit const* victim, bool force = true) const;
|
||||
void LoadTemplateImmunities();
|
||||
bool IsImmunedToSpell(SpellInfo const* spellInfo, Unit* caster) const override;
|
||||
bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const override;
|
||||
bool IsImmunedToSpell(SpellInfo const* spellInfo, WorldObject const* caster) const override;
|
||||
bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, WorldObject const* caster) const override;
|
||||
bool isElite() const;
|
||||
bool isWorldBoss() const;
|
||||
|
||||
|
||||
@@ -226,6 +226,12 @@ void DynamicObject::RemoveCasterViewpoint()
|
||||
}
|
||||
}
|
||||
|
||||
uint32 DynamicObject::GetFaction() const
|
||||
{
|
||||
ASSERT(_caster);
|
||||
return _caster->GetFaction();
|
||||
}
|
||||
|
||||
void DynamicObject::BindToCaster()
|
||||
{
|
||||
ASSERT(!_caster);
|
||||
|
||||
@@ -61,11 +61,13 @@ class TC_GAME_API DynamicObject : public WorldObject, public GridObject<DynamicO
|
||||
void SetCasterViewpoint();
|
||||
void RemoveCasterViewpoint();
|
||||
Unit* GetCaster() const { return _caster; }
|
||||
uint32 GetFaction() const override;
|
||||
void BindToCaster();
|
||||
void UnbindFromCaster();
|
||||
uint32 GetSpellId() const { return m_dynamicObjectData->SpellID; }
|
||||
SpellInfo const* GetSpellInfo() const;
|
||||
ObjectGuid GetCasterGUID() const { return m_dynamicObjectData->Caster; }
|
||||
ObjectGuid GetOwnerGUID() const override { return GetCasterGUID(); }
|
||||
float GetRadius() const { return m_dynamicObjectData->Radius; }
|
||||
|
||||
UF::UpdateField<UF::DynamicObjectData, 0, TYPEID_DYNAMICOBJECT> m_dynamicObjectData;
|
||||
|
||||
@@ -517,6 +517,8 @@ GameObject* GameObject::CreateGameObjectFromDB(ObjectGuid::LowType spawnId, Map*
|
||||
|
||||
void GameObject::Update(uint32 diff)
|
||||
{
|
||||
m_Events.Update(diff);
|
||||
|
||||
if (AI())
|
||||
AI()->UpdateAI(diff);
|
||||
else if (!AIM_Initialize())
|
||||
@@ -825,8 +827,10 @@ void GameObject::Update(uint32 diff)
|
||||
else if (Unit* target = ObjectAccessor::GetUnit(*this, m_lootStateUnitGUID))
|
||||
{
|
||||
// Some traps do not have a spell but should be triggered
|
||||
CastSpellExtraArgs args;
|
||||
args.SetOriginalCaster(GetOwnerGUID());
|
||||
if (goInfo->trap.spell)
|
||||
CastSpell(target, goInfo->trap.spell);
|
||||
CastSpell(target, goInfo->trap.spell, args);
|
||||
|
||||
// Template value or 4 seconds
|
||||
m_cooldownTime = GameTime::GetGameTimeMS() + (goInfo->trap.cooldown ? goInfo->trap.cooldown : uint32(4)) * IN_MILLISECONDS;
|
||||
@@ -1307,11 +1311,6 @@ bool GameObject::IsDestructibleBuilding() const
|
||||
return gInfo->type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING;
|
||||
}
|
||||
|
||||
Unit* GameObject::GetOwner() const
|
||||
{
|
||||
return ObjectAccessor::GetUnit(*this, GetOwnerGUID());
|
||||
}
|
||||
|
||||
void GameObject::SaveRespawnTime(uint32 forceDelay, bool savetodb)
|
||||
{
|
||||
if (m_goData && (forceDelay || m_respawnTime > GameTime::GetGameTime()) && m_spawnedByDefault)
|
||||
@@ -2211,68 +2210,6 @@ void GameObject::Use(Unit* user)
|
||||
CastSpell(user, spellId);
|
||||
}
|
||||
|
||||
void GameObject::CastSpell(Unit* target, uint32 spellId, bool triggered /* = true*/)
|
||||
{
|
||||
CastSpell(target, spellId, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE);
|
||||
}
|
||||
|
||||
void GameObject::CastSpell(Unit* target, uint32 spellId, TriggerCastFlags triggered)
|
||||
{
|
||||
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId, GetMap()->GetDifficultyID());
|
||||
if (!spellInfo)
|
||||
return;
|
||||
|
||||
bool self = false;
|
||||
for (SpellEffectInfo const* effect : spellInfo->GetEffects())
|
||||
{
|
||||
if (effect && effect->TargetA.GetTarget() == TARGET_UNIT_CASTER)
|
||||
{
|
||||
self = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (self)
|
||||
{
|
||||
if (target)
|
||||
target->CastSpell(target, spellInfo->Id, triggered);
|
||||
return;
|
||||
}
|
||||
|
||||
//summon world trigger
|
||||
Creature* trigger = SummonTrigger(GetPositionX(), GetPositionY(), GetPositionZ(), 0, spellInfo->CalcCastTime() + 100);
|
||||
if (!trigger)
|
||||
return;
|
||||
|
||||
// remove immunity flags, to allow spell to target anything
|
||||
trigger->SetImmuneToAll(false);
|
||||
PhasingHandler::InheritPhaseShift(trigger, this);
|
||||
|
||||
CastSpellExtraArgs args;
|
||||
args.TriggerFlags = triggered;
|
||||
if (Unit* owner = GetOwner())
|
||||
{
|
||||
trigger->SetFaction(owner->GetFaction());
|
||||
if (owner->HasUnitFlag(UNIT_FLAG_PVP_ATTACKABLE))
|
||||
trigger->AddUnitFlag(UNIT_FLAG_PVP_ATTACKABLE);
|
||||
// copy pvp state flags from owner
|
||||
trigger->SetPvpFlags(owner->GetPvpFlags());
|
||||
// needed for GO casts for proper target validation checks
|
||||
trigger->SetOwnerGUID(owner->GetGUID());
|
||||
|
||||
args.OriginalCaster = owner->GetGUID();
|
||||
trigger->CastSpell(target ? target : trigger, spellInfo->Id, args);
|
||||
}
|
||||
else
|
||||
{
|
||||
trigger->SetFaction(spellInfo->IsPositive() ? FACTION_FRIENDLY : FACTION_MONSTER);
|
||||
// Set owner guid for target if no owner available - needed by trigger auras
|
||||
// - trigger gets despawned and there's no caster avalible (see AuraEffect::TriggerSpell())
|
||||
args.OriginalCaster = target ? target->GetGUID() : ObjectGuid::Empty;
|
||||
trigger->CastSpell(target ? target : trigger, spellInfo->Id, args);
|
||||
}
|
||||
}
|
||||
|
||||
void GameObject::SendCustomAnim(uint32 anim)
|
||||
{
|
||||
WorldPackets::GameObject::GameObjectCustomAnim customAnim;
|
||||
@@ -2380,7 +2317,7 @@ void GameObject::SetWorldRotationAngles(float z_rot, float y_rot, float x_rot)
|
||||
SetWorldRotation(quat.x, quat.y, quat.z, quat.w);
|
||||
}
|
||||
|
||||
void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= nullptr*/, uint32 spellId /*= 0*/)
|
||||
void GameObject::ModifyHealth(int32 change, WorldObject* attackerOrHealer /*= nullptr*/, uint32 spellId /*= 0*/)
|
||||
{
|
||||
if (!m_goValue.Building.MaxHealth || !change)
|
||||
return;
|
||||
@@ -2399,10 +2336,8 @@ void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= nullptr*/
|
||||
// Set the health bar, value = 255 * healthPct;
|
||||
SetGoAnimProgress(m_goValue.Building.Health * 255 / m_goValue.Building.MaxHealth);
|
||||
|
||||
Player* player = attackerOrHealer ? attackerOrHealer->GetCharmerOrOwnerPlayerOrPlayerItself() : nullptr;
|
||||
|
||||
// dealing damage, send packet
|
||||
if (player)
|
||||
if (Player* player = attackerOrHealer ? attackerOrHealer->GetCharmerOrOwnerPlayerOrPlayerItself() : nullptr)
|
||||
{
|
||||
WorldPackets::GameObject::DestructibleBuildingDamage packet;
|
||||
packet.Caster = attackerOrHealer->GetGUID(); // todo: this can be a GameObject
|
||||
@@ -2425,11 +2360,10 @@ void GameObject::ModifyHealth(int32 change, Unit* attackerOrHealer /*= nullptr*/
|
||||
if (newState == GetDestructibleState())
|
||||
return;
|
||||
|
||||
/// @todo: pass attackerOrHealer instead of player
|
||||
SetDestructibleState(newState, player, false);
|
||||
SetDestructibleState(newState, attackerOrHealer, false);
|
||||
}
|
||||
|
||||
void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player* eventInvoker /*= nullptr*/, bool setHealth /*= false*/)
|
||||
void GameObject::SetDestructibleState(GameObjectDestructibleState state, WorldObject* attackerOrHealer /*= nullptr*/, bool setHealth /*= false*/)
|
||||
{
|
||||
// the user calling this must know he is already operating on destructible gameobject
|
||||
ASSERT(GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING);
|
||||
@@ -2448,8 +2382,8 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
|
||||
break;
|
||||
case GO_DESTRUCTIBLE_DAMAGED:
|
||||
{
|
||||
EventInform(m_goInfo->destructibleBuilding.DamagedEvent, eventInvoker);
|
||||
AI()->Damaged(eventInvoker, m_goInfo->destructibleBuilding.DamagedEvent);
|
||||
EventInform(m_goInfo->destructibleBuilding.DamagedEvent, attackerOrHealer);
|
||||
AI()->Damaged(attackerOrHealer, m_goInfo->destructibleBuilding.DamagedEvent);
|
||||
|
||||
RemoveFlag(GO_FLAG_DESTROYED);
|
||||
AddFlag(GO_FLAG_DAMAGED);
|
||||
@@ -2473,11 +2407,12 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
|
||||
}
|
||||
case GO_DESTRUCTIBLE_DESTROYED:
|
||||
{
|
||||
EventInform(m_goInfo->destructibleBuilding.DestroyedEvent, eventInvoker);
|
||||
AI()->Destroyed(eventInvoker, m_goInfo->destructibleBuilding.DestroyedEvent);
|
||||
if (eventInvoker)
|
||||
if (Battleground* bg = eventInvoker->GetBattleground())
|
||||
bg->DestroyGate(eventInvoker, this);
|
||||
EventInform(m_goInfo->destructibleBuilding.DestroyedEvent, attackerOrHealer);
|
||||
AI()->Destroyed(attackerOrHealer, m_goInfo->destructibleBuilding.DestroyedEvent);
|
||||
|
||||
if (attackerOrHealer && attackerOrHealer->GetTypeId() == TYPEID_PLAYER)
|
||||
if (Battleground* bg = attackerOrHealer->ToPlayer()->GetBattleground())
|
||||
bg->DestroyGate(attackerOrHealer->ToPlayer(), this);
|
||||
|
||||
RemoveFlag(GO_FLAG_DAMAGED);
|
||||
AddFlag(GO_FLAG_DESTROYED);
|
||||
@@ -2498,7 +2433,7 @@ void GameObject::SetDestructibleState(GameObjectDestructibleState state, Player*
|
||||
}
|
||||
case GO_DESTRUCTIBLE_REBUILDING:
|
||||
{
|
||||
EventInform(m_goInfo->destructibleBuilding.RebuildingEvent, eventInvoker);
|
||||
EventInform(m_goInfo->destructibleBuilding.RebuildingEvent, attackerOrHealer);
|
||||
RemoveFlag(GameObjectFlags(GO_FLAG_DAMAGED | GO_FLAG_DESTROYED));
|
||||
|
||||
uint32 modelId = m_goInfo->displayId;
|
||||
|
||||
@@ -140,8 +140,7 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
|
||||
m_spawnedByDefault = false; // all object with owner is despawned after delay
|
||||
SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::CreatedBy), owner);
|
||||
}
|
||||
ObjectGuid GetOwnerGUID() const { return m_gameObjectData->CreatedBy; }
|
||||
Unit* GetOwner() const;
|
||||
ObjectGuid GetOwnerGUID() const override { return m_gameObjectData->CreatedBy; }
|
||||
|
||||
void SetSpellId(uint32 id)
|
||||
{
|
||||
@@ -249,14 +248,12 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
|
||||
|
||||
GameObject* LookupFishingHoleAround(float range);
|
||||
|
||||
void CastSpell(Unit* target, uint32 spell, bool triggered = true);
|
||||
void CastSpell(Unit* target, uint32 spell, TriggerCastFlags triggered);
|
||||
void SendCustomAnim(uint32 anim);
|
||||
bool IsInRange(float x, float y, float z, float radius) const;
|
||||
|
||||
void ModifyHealth(int32 change, Unit* attackerOrHealer = nullptr, uint32 spellId = 0);
|
||||
void ModifyHealth(int32 change, WorldObject* attackerOrHealer = nullptr, uint32 spellId = 0);
|
||||
// sets GameObject type 33 destruction flags and optionally default health for that state
|
||||
void SetDestructibleState(GameObjectDestructibleState state, Player* eventInvoker = nullptr, bool setHealth = false);
|
||||
void SetDestructibleState(GameObjectDestructibleState state, WorldObject* attackerOrHealer = nullptr, bool setHealth = false);
|
||||
GameObjectDestructibleState GetDestructibleState() const
|
||||
{
|
||||
if ((*m_gameObjectData->Flags & GO_FLAG_DESTROYED))
|
||||
@@ -280,8 +277,8 @@ class TC_GAME_API GameObject : public WorldObject, public GridObject<GameObject>
|
||||
uint32 GetDisplayId() const { return m_gameObjectData->DisplayID; }
|
||||
uint8 GetNameSetId() const;
|
||||
|
||||
uint32 GetFaction() const { return m_gameObjectData->FactionTemplate; }
|
||||
void SetFaction(uint32 faction) { SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::FactionTemplate), faction); }
|
||||
uint32 GetFaction() const override { return m_gameObjectData->FactionTemplate; }
|
||||
void SetFaction(uint32 faction) override { SetUpdateFieldValue(m_values.ModifyValue(&GameObject::m_gameObjectData).ModifyValue(&UF::GameObjectData::FactionTemplate), faction); }
|
||||
|
||||
GameObjectModel* m_model;
|
||||
void GetRespawnPosition(float &x, float &y, float &z, float* ori = nullptr) const;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "Common.h"
|
||||
#include "Duration.h"
|
||||
#include "EventProcessor.h"
|
||||
#include "GridReference.h"
|
||||
#include "GridRefManager.h"
|
||||
#include "ModelIgnoreFlags.h"
|
||||
@@ -47,6 +48,9 @@ class Map;
|
||||
class Object;
|
||||
class Player;
|
||||
class Scenario;
|
||||
class Spell;
|
||||
class SpellCastTargets;
|
||||
class SpellInfo;
|
||||
class TempSummon;
|
||||
class Transport;
|
||||
class Unit;
|
||||
@@ -54,9 +58,18 @@ class UpdateData;
|
||||
class WorldObject;
|
||||
class WorldPacket;
|
||||
class ZoneScript;
|
||||
struct FactionTemplateEntry;
|
||||
struct PositionFullTerrainStatus;
|
||||
struct QuaternionData;
|
||||
|
||||
namespace WorldPackets
|
||||
{
|
||||
namespace CombatLog
|
||||
{
|
||||
class CombatLogServerPacket;
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::unordered_map<Player*, UpdateData> UpdateDataMapType;
|
||||
|
||||
struct CreateObjectBits
|
||||
@@ -400,7 +413,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
public:
|
||||
virtual ~WorldObject();
|
||||
|
||||
virtual void Update (uint32 /*time_diff*/) { }
|
||||
virtual void Update(uint32 /*time_diff*/) { }
|
||||
|
||||
void AddToWorld() override;
|
||||
void RemoveFromWorld() override;
|
||||
@@ -491,6 +504,8 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
virtual void SendMessageToSetInRange(WorldPacket const* data, float dist, bool self) const;
|
||||
virtual void SendMessageToSet(WorldPacket const* data, Player const* skipped_rcvr) const;
|
||||
|
||||
void SendCombatLogMessage(WorldPackets::CombatLog::CombatLogServerPacket* combatLog) const;
|
||||
|
||||
virtual uint8 GetLevelForTarget(WorldObject const* /*target*/) const { return 1; }
|
||||
|
||||
void PlayDistanceSound(uint32 soundId, Player* target = nullptr);
|
||||
@@ -538,6 +553,61 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
GameObject* FindNearestGameObjectOfType(GameobjectTypes type, float range) const;
|
||||
Player* SelectNearestPlayer(float distance) const;
|
||||
|
||||
virtual ObjectGuid GetOwnerGUID() const = 0;
|
||||
virtual ObjectGuid GetCharmerOrOwnerGUID() const { return GetOwnerGUID(); }
|
||||
ObjectGuid GetCharmerOrOwnerOrOwnGUID() const;
|
||||
|
||||
Unit* GetOwner() const;
|
||||
Unit* GetCharmerOrOwner() const;
|
||||
Unit* GetCharmerOrOwnerOrSelf() const;
|
||||
Player* GetCharmerOrOwnerPlayerOrPlayerItself() const;
|
||||
Player* GetAffectingPlayer() const;
|
||||
|
||||
Player* GetSpellModOwner() const;
|
||||
int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellInfo, uint8 effIndex, int32 const* basePoints = nullptr, float* variance = nullptr, uint32 castItemId = 0, int32 itemLevel = -1) const;
|
||||
|
||||
// target dependent range checks
|
||||
float GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
|
||||
float GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
|
||||
|
||||
float ApplyEffectModifiers(SpellInfo const* spellInfo, uint8 effIndex, float value) const;
|
||||
int32 CalcSpellDuration(SpellInfo const* spellInfo) const;
|
||||
int32 ModSpellDuration(SpellInfo const* spellInfo, WorldObject const* target, int32 duration, bool positive, uint32 effectMask) const;
|
||||
void ModSpellCastTime(SpellInfo const* spellInfo, int32& castTime, Spell* spell = nullptr) const;
|
||||
void ModSpellDurationTime(SpellInfo const* spellInfo, int32& durationTime, Spell* spell = nullptr) const;
|
||||
|
||||
virtual float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, SpellInfo const* spellInfo) const;
|
||||
virtual SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo) const;
|
||||
SpellMissInfo MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo) const;
|
||||
SpellMissInfo SpellHitResult(Unit* victim, SpellInfo const* spellInfo, bool canReflect = false) const;
|
||||
|
||||
virtual uint32 GetFaction() const = 0;
|
||||
virtual void SetFaction(uint32 /*faction*/) { }
|
||||
FactionTemplateEntry const* GetFactionTemplateEntry() const;
|
||||
|
||||
ReputationRank GetReactionTo(WorldObject const* target) const;
|
||||
static ReputationRank GetFactionReactionTo(FactionTemplateEntry const* factionTemplateEntry, WorldObject const* target);
|
||||
|
||||
bool IsHostileTo(WorldObject const* target) const;
|
||||
bool IsHostileToPlayers() const;
|
||||
bool IsFriendlyTo(WorldObject const* target) const;
|
||||
bool IsNeutralToAll() const;
|
||||
|
||||
// CastSpell's third arg can be a variety of things - check out CastSpellExtraArgs' constructors!
|
||||
void CastSpell(SpellCastTargets const& targets, uint32 spellId, CastSpellExtraArgs const& args = { });
|
||||
void CastSpell(WorldObject* target, uint32 spellId, CastSpellExtraArgs const& args = { });
|
||||
void CastSpell(Position const& dest, uint32 spellId, CastSpellExtraArgs const& args = { });
|
||||
|
||||
bool IsValidAttackTarget(WorldObject const* target, SpellInfo const* bySpell = nullptr, bool spellCheck = true) const;
|
||||
bool IsValidSpellAttackTarget(WorldObject const* target, SpellInfo const* bySpell) const;
|
||||
|
||||
bool IsValidAssistTarget(WorldObject const* target, SpellInfo const* bySpell = nullptr, bool spellCheck = true) const;
|
||||
bool IsValidSpellAssistTarget(WorldObject const* target, SpellInfo const* bySpell) const;
|
||||
|
||||
Unit* GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo);
|
||||
|
||||
virtual uint32 GetCastSpellXSpellVisualId(SpellInfo const* spellInfo) const;
|
||||
|
||||
template <typename Container>
|
||||
void GetGameObjectListWithEntryInGrid(Container& gameObjectContainer, uint32 entry, float maxSearchRange = 250.0f) const;
|
||||
|
||||
@@ -599,6 +669,9 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
float GetMapWaterOrGroundLevel(float x, float y, float z, float* ground = nullptr) const;
|
||||
float GetMapHeight(float x, float y, float z, bool vmap = true, float distanceToSearch = 50.0f) const; // DEFAULT_HEIGHT_SEARCH in map.h
|
||||
|
||||
// Event handler
|
||||
EventProcessor m_Events;
|
||||
|
||||
virtual uint16 GetAIAnimKitId() const { return 0; }
|
||||
virtual uint16 GetMovementAnimKitId() const { return 0; }
|
||||
virtual uint16 GetMeleeAnimKitId() const { return 0; }
|
||||
@@ -614,7 +687,7 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
bool m_isActive;
|
||||
bool m_isFarVisible;
|
||||
Optional<float> m_visibilityDistanceOverride;
|
||||
const bool m_isWorldObject;
|
||||
bool const m_isWorldObject;
|
||||
ZoneScript* m_zoneScript;
|
||||
|
||||
// transports
|
||||
@@ -640,7 +713,6 @@ class TC_GAME_API WorldObject : public Object, public WorldLocation
|
||||
private:
|
||||
Map* m_currMap; // current object's Map location
|
||||
|
||||
//uint32 m_mapId; // object at map with map_id
|
||||
uint32 m_InstanceId; // in map copy with instance id
|
||||
PhaseShift _phaseShift;
|
||||
PhaseShift _suppressedPhaseShift; // contains phases for current area but not applied due to conditions
|
||||
|
||||
@@ -1663,7 +1663,7 @@ void Player::SetObjectScale(float scale)
|
||||
SendMovementSetCollisionHeight(scale * GetCollisionHeight(), WorldPackets::Movement::UpdateCollisionHeightReason::Scale);
|
||||
}
|
||||
|
||||
bool Player::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const
|
||||
bool Player::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, WorldObject const* caster) const
|
||||
{
|
||||
SpellEffectInfo const* effect = spellInfo->GetEffect(index);
|
||||
if (!effect || !effect->IsEffect())
|
||||
@@ -23424,7 +23424,7 @@ void Player::UpdatePotionCooldown(Spell* spell)
|
||||
m_lastPotionId = 0;
|
||||
}
|
||||
|
||||
void Player::SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura)
|
||||
void Player::SetResurrectRequestData(WorldObject const* caster, uint32 health, uint32 mana, uint32 appliedAura)
|
||||
{
|
||||
ASSERT(!IsResurrectRequested());
|
||||
_resurrectionData.reset(new ResurrectionData());
|
||||
@@ -24082,45 +24082,6 @@ Player* Player::GetSelectedPlayer() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void Player::AddComboPoints(int8 count, Spell* spell)
|
||||
{
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
int8 comboPoints = spell ? spell->m_comboPointGain : GetPower(POWER_COMBO_POINTS);
|
||||
|
||||
comboPoints += count;
|
||||
|
||||
if (comboPoints > 5)
|
||||
comboPoints = 5;
|
||||
else if (comboPoints < 0)
|
||||
comboPoints = 0;
|
||||
|
||||
if (!spell)
|
||||
SetPower(POWER_COMBO_POINTS, comboPoints);
|
||||
else
|
||||
spell->m_comboPointGain = comboPoints;
|
||||
}
|
||||
|
||||
void Player::GainSpellComboPoints(int8 count)
|
||||
{
|
||||
if (!count)
|
||||
return;
|
||||
|
||||
int8 cp = GetPower(POWER_COMBO_POINTS);
|
||||
|
||||
cp += count;
|
||||
if (cp > 5) cp = 5;
|
||||
else if (cp < 0) cp = 0;
|
||||
|
||||
SetPower(POWER_COMBO_POINTS, cp);
|
||||
}
|
||||
|
||||
void Player::ClearComboPoints()
|
||||
{
|
||||
SetPower(POWER_COMBO_POINTS, 0);
|
||||
}
|
||||
|
||||
bool Player::IsInGroup(ObjectGuid groupGuid) const
|
||||
{
|
||||
if (Group const* group = GetGroup())
|
||||
@@ -26626,10 +26587,10 @@ void Player::ResetCriteria(CriteriaFailEvent condition, int32 failAsset, bool ev
|
||||
m_questObjectiveCriteriaMgr->ResetCriteria(condition, failAsset, evenIfCriteriaComplete);
|
||||
}
|
||||
|
||||
void Player::UpdateCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, Unit* unit /*= nullptr*/)
|
||||
void Player::UpdateCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0*/, uint64 miscValue2 /*= 0*/, uint64 miscValue3 /*= 0*/, WorldObject* ref /*= nullptr*/)
|
||||
{
|
||||
m_achievementMgr->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, unit, this);
|
||||
m_questObjectiveCriteriaMgr->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, unit, this);
|
||||
m_achievementMgr->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, ref, this);
|
||||
m_questObjectiveCriteriaMgr->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, ref, this);
|
||||
|
||||
// Update only individual achievement criteria here, otherwise we may get multiple updates
|
||||
// from a single boss kill
|
||||
@@ -26637,10 +26598,10 @@ void Player::UpdateCriteria(CriteriaTypes type, uint64 miscValue1 /*= 0*/, uint6
|
||||
return;
|
||||
|
||||
if (Scenario* scenario = GetScenario())
|
||||
scenario->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, unit, this);
|
||||
scenario->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, ref, this);
|
||||
|
||||
if (Guild* guild = sGuildMgr->GetGuildById(GetGuildId()))
|
||||
guild->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, unit, this);
|
||||
guild->UpdateCriteria(type, miscValue1, miscValue2, miscValue3, ref, this);
|
||||
}
|
||||
|
||||
void Player::CompletedAchievement(AchievementEntry const* entry)
|
||||
|
||||
@@ -1085,7 +1085,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
|
||||
void Update(uint32 time) override;
|
||||
|
||||
bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const override;
|
||||
bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, WorldObject const* caster) const override;
|
||||
|
||||
void SetInWater(bool inWater) override;
|
||||
|
||||
@@ -1664,11 +1664,6 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void SetTarget(ObjectGuid const& /*guid*/) override { } /// Used for serverside target changes, does not apply to players
|
||||
void SetSelection(ObjectGuid const& guid) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::Target), guid); }
|
||||
|
||||
uint32 GetComboPoints() const { return uint32(GetPower(POWER_COMBO_POINTS)); }
|
||||
void AddComboPoints(int8 count, Spell* spell = nullptr);
|
||||
void GainSpellComboPoints(int8 count);
|
||||
void ClearComboPoints();
|
||||
|
||||
void SendMailResult(uint32 mailId, MailResponseType mailAction, MailResponseResult mailError, uint32 equipError = 0, ObjectGuid::LowType item_guid = UI64LIT(0), uint32 item_count = 0) const;
|
||||
void SendNewMail() const;
|
||||
void UpdateNextMailTimeAndUnreads();
|
||||
@@ -1816,7 +1811,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
void SetLastPotionId(uint32 item_id) { m_lastPotionId = item_id; }
|
||||
void UpdatePotionCooldown(Spell* spell = nullptr);
|
||||
|
||||
void SetResurrectRequestData(Unit* caster, uint32 health, uint32 mana, uint32 appliedAura);
|
||||
void SetResurrectRequestData(WorldObject const* caster, uint32 health, uint32 mana, uint32 appliedAura);
|
||||
void ClearResurrectRequestData()
|
||||
{
|
||||
_resurrectionData.reset();
|
||||
@@ -2499,7 +2494,7 @@ class TC_GAME_API Player : public Unit, public GridObject<Player>
|
||||
bool HasAchieved(uint32 achievementId) const;
|
||||
void ResetAchievements();
|
||||
void ResetCriteria(CriteriaFailEvent condition, int32 failAsset, bool evenIfCriteriaComplete = false);
|
||||
void UpdateCriteria(CriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, Unit* unit = nullptr);
|
||||
void UpdateCriteria(CriteriaTypes type, uint64 miscValue1 = 0, uint64 miscValue2 = 0, uint64 miscValue3 = 0, WorldObject* ref = nullptr);
|
||||
void StartCriteriaTimer(CriteriaStartEvent startEvent, uint32 entry, uint32 timeLost = 0);
|
||||
void RemoveCriteriaTimer(CriteriaStartEvent startEvent, uint32 entry);
|
||||
void CompletedAchievement(AchievementEntry const* entry);
|
||||
|
||||
@@ -137,7 +137,7 @@ void Totem::UnSummon(uint32 msTime)
|
||||
AddObjectToRemoveList();
|
||||
}
|
||||
|
||||
bool Totem::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const
|
||||
bool Totem::IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, WorldObject const* caster) const
|
||||
{
|
||||
/// @todo possibly all negative auras immune?
|
||||
if (GetEntry() == 5925)
|
||||
|
||||
@@ -50,7 +50,7 @@ class TC_GAME_API Totem : public Minion
|
||||
void UpdateAttackPowerAndDamage(bool /*ranged*/) override { }
|
||||
void UpdateDamagePhysical(WeaponAttackType /*attType*/) override { }
|
||||
|
||||
bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const override;
|
||||
bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, WorldObject const* caster) const override;
|
||||
|
||||
protected:
|
||||
TotemType m_type;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -19,13 +19,11 @@
|
||||
#define __UNIT_H
|
||||
|
||||
#include "Object.h"
|
||||
#include "EventProcessor.h"
|
||||
#include "FollowerReference.h"
|
||||
#include "FollowerRefManager.h"
|
||||
#include "CombatManager.h"
|
||||
#include "OptionalFwd.h"
|
||||
#include "SpellAuraDefines.h"
|
||||
#include "SpellDefines.h"
|
||||
#include "ThreatManager.h"
|
||||
#include "Timer.h"
|
||||
#include "UnitDefines.h"
|
||||
@@ -105,13 +103,6 @@ namespace Movement
|
||||
class MoveSpline;
|
||||
struct SpellEffectExtraData;
|
||||
}
|
||||
namespace WorldPackets
|
||||
{
|
||||
namespace CombatLog
|
||||
{
|
||||
class CombatLogServerPacket;
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::list<Unit*> UnitList;
|
||||
|
||||
@@ -383,15 +374,15 @@ enum MeleeHitOutcome : uint8
|
||||
class DispelInfo
|
||||
{
|
||||
public:
|
||||
explicit DispelInfo(Unit* dispeller, uint32 dispellerSpellId, uint8 chargesRemoved) :
|
||||
_dispellerUnit(dispeller), _dispellerSpell(dispellerSpellId), _chargesRemoved(chargesRemoved) { }
|
||||
explicit DispelInfo(WorldObject* dispeller, uint32 dispellerSpellId, uint8 chargesRemoved) :
|
||||
_dispeller(dispeller), _dispellerSpell(dispellerSpellId), _chargesRemoved(chargesRemoved) { }
|
||||
|
||||
Unit* GetDispeller() const { return _dispellerUnit; }
|
||||
WorldObject* GetDispeller() const { return _dispeller; }
|
||||
uint32 GetDispellerSpellId() const { return _dispellerSpell; }
|
||||
uint8 GetRemovedCharges() const { return _chargesRemoved; }
|
||||
void SetRemovedCharges(uint8 amount) { _chargesRemoved = amount; }
|
||||
private:
|
||||
Unit* _dispellerUnit;
|
||||
WorldObject* _dispeller;
|
||||
uint32 _dispellerSpell;
|
||||
uint8 _chargesRemoved;
|
||||
};
|
||||
@@ -781,19 +772,13 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void CleanupBeforeRemoveFromMap(bool finalCleanup);
|
||||
void CleanupsBeforeDelete(bool finalCleanup = true) override; // used in ~Creature/~Player (or before mass creature delete to remove cross-references to already deleted units)
|
||||
|
||||
void SendCombatLogMessage(WorldPackets::CombatLog::CombatLogServerPacket* combatLog) const;
|
||||
|
||||
virtual bool IsAffectedByDiminishingReturns() const { return (GetCharmerOrOwnerPlayerOrPlayerItself() != nullptr); }
|
||||
DiminishingLevels GetDiminishing(DiminishingGroup group) const;
|
||||
void IncrDiminishing(SpellInfo const* auraSpellInfo);
|
||||
bool ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, int32& duration, Unit* caster, DiminishingLevels previousLevel) const;
|
||||
bool ApplyDiminishingToDuration(SpellInfo const* auraSpellInfo, int32& duration, WorldObject* caster, DiminishingLevels previousLevel) const;
|
||||
void ApplyDiminishingAura(DiminishingGroup group, bool apply);
|
||||
void ClearDiminishings();
|
||||
|
||||
// target dependent range checks
|
||||
float GetSpellMaxRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
|
||||
float GetSpellMinRangeForTarget(Unit const* target, SpellInfo const* spellInfo) const;
|
||||
|
||||
virtual void Update(uint32 time) override;
|
||||
|
||||
void setAttackTimer(WeaponAttackType type, uint32 time) { m_attackTimer[type] = time; }
|
||||
@@ -881,7 +866,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
int32 GetResistance(SpellSchoolMask mask) const;
|
||||
void SetResistance(SpellSchools school, int32 val) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::Resistances, school), val); }
|
||||
void SetBonusResistanceMod(SpellSchools school, int32 val) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::BonusResistanceMods, school), val); }
|
||||
static float CalculateAverageResistReduction(Unit const* attacker, SpellSchoolMask schoolMask, Unit const* victim, SpellInfo const* spellInfo = nullptr);
|
||||
static float CalculateAverageResistReduction(WorldObject const* caster, SpellSchoolMask schoolMask, Unit const* victim, SpellInfo const* spellInfo = nullptr);
|
||||
|
||||
uint64 GetHealth() const { return m_unitData->Health; }
|
||||
uint64 GetMaxHealth() const { return m_unitData->MaxHealth; }
|
||||
@@ -959,17 +944,9 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void SetSheath(SheathState sheathed);
|
||||
|
||||
// faction template id
|
||||
uint32 GetFaction() const { return m_unitData->FactionTemplate; }
|
||||
void SetFaction(uint32 faction) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::FactionTemplate), faction); }
|
||||
FactionTemplateEntry const* GetFactionTemplateEntry() const;
|
||||
uint32 GetFaction() const override { return m_unitData->FactionTemplate; }
|
||||
void SetFaction(uint32 faction) override { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::FactionTemplate), faction); }
|
||||
|
||||
ReputationRank GetReactionTo(Unit const* target) const;
|
||||
ReputationRank static GetFactionReactionTo(FactionTemplateEntry const* factionTemplateEntry, Unit const* target);
|
||||
|
||||
bool IsHostileTo(Unit const* unit) const;
|
||||
bool IsHostileToPlayers() const;
|
||||
bool IsFriendlyTo(Unit const* unit) const;
|
||||
bool IsNeutralToAll() const;
|
||||
bool IsInPartyWith(Unit const* unit) const;
|
||||
bool IsInRaidWith(Unit const* unit) const;
|
||||
void GetPartyMembers(std::list<Unit*> &units);
|
||||
@@ -1057,10 +1034,8 @@ class TC_GAME_API Unit : public WorldObject
|
||||
|
||||
int32 CalculateAOEAvoidance(int32 damage, uint32 schoolMask, ObjectGuid const& casterGuid) const;
|
||||
|
||||
float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, SpellInfo const* spellInfo) const;
|
||||
SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo) const;
|
||||
SpellMissInfo MagicSpellHitResult(Unit* victim, SpellInfo const* spellInfo) const;
|
||||
SpellMissInfo SpellHitResult(Unit* victim, SpellInfo const* spellInfo, bool canReflect = false);
|
||||
float MeleeSpellMissChance(Unit const* victim, WeaponAttackType attType, SpellInfo const* spellInfo) const override;
|
||||
SpellMissInfo MeleeSpellHitResult(Unit* victim, SpellInfo const* spellInfo) const override;
|
||||
|
||||
float GetUnitDodgeChance(WeaponAttackType attType, Unit const* victim) const;
|
||||
float GetUnitParryChance(WeaponAttackType attType, Unit const* victim) const;
|
||||
@@ -1161,12 +1136,6 @@ class TC_GAME_API Unit : public WorldObject
|
||||
|
||||
bool isTargetableForAttack(bool checkFakeDeath = true) const;
|
||||
|
||||
bool IsValidAttackTarget(Unit const* target, SpellInfo const* bySpell = nullptr, WorldObject const* obj = nullptr, bool spellCheck = true) const;
|
||||
bool IsValidSpellAttackTarget(Unit const* target, SpellInfo const* bySpell, WorldObject const* obj = nullptr) const;
|
||||
|
||||
bool IsValidAssistTarget(Unit const* target, SpellInfo const* bySpell = nullptr, bool spellCheck = true) const;
|
||||
bool IsValidSpellAssistTarget(Unit const* target, SpellInfo const* bySpell) const;
|
||||
|
||||
virtual bool IsInWater() const;
|
||||
virtual bool IsUnderWater() const;
|
||||
bool isInAccessiblePlaceFor(Creature const* c) const;
|
||||
@@ -1176,10 +1145,6 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void SendEnergizeSpellLog(Unit* victim, uint32 spellId, int32 damage, int32 overEnergize, Powers powerType);
|
||||
void EnergizeBySpell(Unit* victim, SpellInfo const* spellInfo, int32 damage, Powers powerType);
|
||||
|
||||
// CastSpell's third arg can be a variety of things - check out CastSpellExtraArgs' constructors!
|
||||
void CastSpell(SpellCastTargets const& targets, uint32 spellId, CastSpellExtraArgs const& args = {});
|
||||
void CastSpell(WorldObject* target, uint32 spellId, CastSpellExtraArgs const& args = {});
|
||||
void CastSpell(Position const& dest, uint32 spellId, CastSpellExtraArgs const& args = {});
|
||||
Aura* AddAura(uint32 spellId, Unit* target);
|
||||
Aura* AddAura(SpellInfo const* spellInfo, uint32 effMask, Unit* target);
|
||||
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
|
||||
@@ -1256,7 +1221,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
DeathState getDeathState() const { return m_deathState; }
|
||||
virtual void setDeathState(DeathState s); // overwrited in Creature/Player/Pet
|
||||
|
||||
ObjectGuid GetOwnerGUID() const { return m_unitData->SummonedBy; }
|
||||
ObjectGuid GetOwnerGUID() const override { return m_unitData->SummonedBy; }
|
||||
void SetOwnerGUID(ObjectGuid owner);
|
||||
ObjectGuid GetCreatorGUID() const { return m_unitData->CreatedBy; }
|
||||
void SetCreatorGUID(ObjectGuid creator) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::CreatedBy), creator); }
|
||||
@@ -1276,21 +1241,14 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void SetDemonCreatorGUID(ObjectGuid guid) { SetUpdateFieldValue(m_values.ModifyValue(&Unit::m_unitData).ModifyValue(&UF::UnitData::DemonCreator), guid); }
|
||||
|
||||
bool IsControlledByPlayer() const { return m_ControlledByPlayer; }
|
||||
ObjectGuid GetCharmerOrOwnerGUID() const;
|
||||
ObjectGuid GetCharmerOrOwnerOrOwnGUID() const;
|
||||
ObjectGuid GetCharmerOrOwnerGUID() const override;
|
||||
bool IsCharmedOwnedByPlayerOrPlayer() const { return GetCharmerOrOwnerOrOwnGUID().IsPlayer(); }
|
||||
|
||||
Player* GetSpellModOwner() const;
|
||||
|
||||
Unit* GetOwner() const;
|
||||
Guardian* GetGuardianPet() const;
|
||||
Minion* GetFirstMinion() const;
|
||||
Unit* GetCharmer() const;
|
||||
Unit* GetCharm() const;
|
||||
Unit* GetCharmerOrOwner() const;
|
||||
Unit* GetCharmerOrOwnerOrSelf() const;
|
||||
Player* GetCharmerOrOwnerPlayerOrPlayerItself() const;
|
||||
Player* GetAffectingPlayer() const;
|
||||
|
||||
void SetMinion(Minion *minion, bool apply);
|
||||
void GetAllMinionsByEntry(std::list<TempSummon*>& Minions, uint32 entry);
|
||||
@@ -1378,8 +1336,8 @@ class TC_GAME_API Unit : public WorldObject
|
||||
|
||||
void RemoveAurasDueToSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT);
|
||||
void RemoveAuraFromStack(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, AuraRemoveMode removeMode = AURA_REMOVE_BY_DEFAULT, uint16 num = 1);
|
||||
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, Unit* dispeller, uint8 chargesRemoved = 1);
|
||||
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, Unit* stealer);
|
||||
void RemoveAurasDueToSpellByDispel(uint32 spellId, uint32 dispellerSpellId, ObjectGuid casterGUID, WorldObject* dispeller, uint8 chargesRemoved = 1);
|
||||
void RemoveAurasDueToSpellBySteal(uint32 spellId, ObjectGuid casterGUID, WorldObject* stealer);
|
||||
void RemoveAurasDueToItemSpell(uint32 spellId, ObjectGuid castItemGuid);
|
||||
void RemoveAurasByType(AuraType auraType, ObjectGuid casterGUID = ObjectGuid::Empty, Aura* except = nullptr, bool negative = true, bool positive = true);
|
||||
void RemoveNotOwnSingleTargetAuras(bool onPhaseChange = false);
|
||||
@@ -1427,7 +1385,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
AuraApplication* GetAuraApplicationOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0, AuraApplication* except = nullptr) const;
|
||||
Aura* GetAuraOfRankedSpell(uint32 spellId, ObjectGuid casterGUID = ObjectGuid::Empty, ObjectGuid itemCasterGUID = ObjectGuid::Empty, uint32 reqEffMask = 0) const;
|
||||
|
||||
void GetDispellableAuraList(Unit* caster, uint32 dispelMask, DispelChargesList& dispelList, bool isReflect = false) const;
|
||||
void GetDispellableAuraList(WorldObject const* caster, uint32 dispelMask, DispelChargesList& dispelList, bool isReflect = false) const;
|
||||
|
||||
bool HasAuraEffect(uint32 spellId, uint8 effIndex, ObjectGuid caster = ObjectGuid::Empty) const;
|
||||
uint32 GetAuraCount(uint32 spellId) const;
|
||||
@@ -1530,7 +1488,7 @@ class TC_GAME_API Unit : public WorldObject
|
||||
Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;
|
||||
int32 GetCurrentSpellCastTime(uint32 spell_id) const;
|
||||
virtual SpellInfo const* GetCastSpellInfo(SpellInfo const* spellInfo) const;
|
||||
uint32 GetCastSpellXSpellVisualId(SpellInfo const* spellInfo) const;
|
||||
uint32 GetCastSpellXSpellVisualId(SpellInfo const* spellInfo) const override;
|
||||
|
||||
virtual bool IsFocusing(Spell const* /*focusSpell*/ = nullptr, bool /*withDelay*/ = false) { return false; }
|
||||
virtual bool IsMovementPreventedByCasting() const;
|
||||
@@ -1559,9 +1517,6 @@ class TC_GAME_API Unit : public WorldObject
|
||||
float m_modAttackSpeedPct[MAX_ATTACK];
|
||||
uint32 m_attackTimer[MAX_ATTACK];
|
||||
|
||||
// Event handler
|
||||
EventProcessor m_Events;
|
||||
|
||||
// stat system
|
||||
void HandleStatFlatModifier(UnitMods unitMod, UnitModifierFlatType modifierType, float amount, bool apply);
|
||||
void ApplyStatPctModifier(UnitMods unitMod, UnitModifierPctType modifierType, float amount);
|
||||
@@ -1688,7 +1643,6 @@ class TC_GAME_API Unit : public WorldObject
|
||||
bool HasAuraState(AuraStateType flag, SpellInfo const* spellProto = nullptr, Unit const* Caster = nullptr) const;
|
||||
void UnsummonAllTotems();
|
||||
bool IsMagnet() const;
|
||||
Unit* GetMagicHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo);
|
||||
Unit* GetMeleeHitRedirectTarget(Unit* victim, SpellInfo const* spellInfo = nullptr);
|
||||
|
||||
int32 SpellBaseDamageBonusDone(SpellSchoolMask schoolMask) const;
|
||||
@@ -1716,14 +1670,14 @@ class TC_GAME_API Unit : public WorldObject
|
||||
uint32 GetRemainingPeriodicAmount(ObjectGuid caster, uint32 spellId, AuraType auraType, uint8 effectIndex = 0) const;
|
||||
|
||||
void ApplySpellImmune(uint32 spellId, uint32 op, uint32 type, bool apply);
|
||||
virtual bool IsImmunedToSpell(SpellInfo const* spellInfo, Unit* caster) const; // redefined in Creature
|
||||
virtual bool IsImmunedToSpell(SpellInfo const* spellInfo, WorldObject const* caster) const;
|
||||
uint32 GetSchoolImmunityMask() const;
|
||||
uint32 GetDamageImmunityMask() const;
|
||||
uint32 GetMechanicImmunityMask() const;
|
||||
|
||||
bool IsImmunedToDamage(SpellSchoolMask meleeSchoolMask) const;
|
||||
bool IsImmunedToDamage(SpellInfo const* spellInfo) const;
|
||||
virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, Unit* caster) const; // redefined in Creature
|
||||
virtual bool IsImmunedToSpellEffect(SpellInfo const* spellInfo, uint32 index, WorldObject const* caster) const;
|
||||
|
||||
static bool IsDamageReducedByArmor(SpellSchoolMask damageSchoolMask, SpellInfo const* spellInfo = nullptr, int8 effIndex = -1);
|
||||
static uint32 CalcArmorReducedDamage(Unit const* attacker, Unit* victim, uint32 damage, SpellInfo const* spellInfo, WeaponAttackType attackType = MAX_ATTACK, uint8 attackerLevel = 0);
|
||||
@@ -1737,13 +1691,6 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void SetSpeed(UnitMoveType mtype, float newValue);
|
||||
void SetSpeedRate(UnitMoveType mtype, float rate);
|
||||
|
||||
float ApplyEffectModifiers(SpellInfo const* spellProto, uint8 effect_index, float value) const;
|
||||
int32 CalculateSpellDamage(Unit const* target, SpellInfo const* spellProto, uint8 effect_index, int32 const* basePoints = nullptr, float* variance = nullptr, uint32 castItemId = 0, int32 itemLevel = -1) const;
|
||||
int32 CalcSpellDuration(SpellInfo const* spellProto);
|
||||
int32 ModSpellDuration(SpellInfo const* spellProto, Unit const* target, int32 duration, bool positive, uint32 effectMask);
|
||||
void ModSpellCastTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = nullptr);
|
||||
void ModSpellDurationTime(SpellInfo const* spellProto, int32& castTime, Spell* spell = nullptr);
|
||||
|
||||
void addFollower(FollowerReference* pRef) { m_FollowingRefManager.insertFirst(pRef); }
|
||||
void removeFollower(FollowerReference* /*pRef*/) { /* nothing to do yet */ }
|
||||
|
||||
@@ -1771,6 +1718,12 @@ class TC_GAME_API Unit : public WorldObject
|
||||
void SetControlled(bool apply, UnitState state);
|
||||
void ApplyControlStatesIfNeeded();
|
||||
|
||||
///-----------Combo point system-------------------
|
||||
uint32 GetComboPoints() const { return uint32(GetPower(POWER_COMBO_POINTS)); }
|
||||
void AddComboPoints(int8 count, Spell* spell = nullptr);
|
||||
void GainSpellComboPoints(int8 count);
|
||||
void ClearComboPoints();
|
||||
|
||||
///----------Pet responses methods-----------------
|
||||
void SendPetActionFeedback(PetActionFeedback msg, uint32 spellId);
|
||||
void SendPetTalk(uint32 pettalk);
|
||||
|
||||
@@ -286,17 +286,17 @@ bool AnyDeadUnitObjectInRangeCheck::operator()(Creature* u)
|
||||
|
||||
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Player* u)
|
||||
{
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && WorldObjectSpellTargetCheck::operator()(u);
|
||||
}
|
||||
|
||||
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Corpse* u)
|
||||
{
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && WorldObjectSpellTargetCheck::operator()(u);
|
||||
}
|
||||
|
||||
bool AnyDeadUnitSpellTargetInRangeCheck::operator()(Creature* u)
|
||||
{
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && i_check(u);
|
||||
return AnyDeadUnitObjectInRangeCheck::operator()(u) && WorldObjectSpellTargetCheck::operator()(u);
|
||||
}
|
||||
|
||||
template void ObjectUpdater::Visit<Creature>(CreatureMapType&);
|
||||
|
||||
@@ -670,29 +670,26 @@ namespace Trinity
|
||||
class TC_GAME_API AnyDeadUnitObjectInRangeCheck
|
||||
{
|
||||
public:
|
||||
AnyDeadUnitObjectInRangeCheck(Unit* searchObj, float range) : i_searchObj(searchObj), i_range(range) { }
|
||||
AnyDeadUnitObjectInRangeCheck(WorldObject* searchObj, float range) : i_searchObj(searchObj), i_range(range) { }
|
||||
bool operator()(Player* u);
|
||||
bool operator()(Corpse* u);
|
||||
bool operator()(Creature* u);
|
||||
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
|
||||
protected:
|
||||
Unit const* const i_searchObj;
|
||||
WorldObject const* const i_searchObj;
|
||||
float i_range;
|
||||
};
|
||||
|
||||
class TC_GAME_API AnyDeadUnitSpellTargetInRangeCheck : public AnyDeadUnitObjectInRangeCheck
|
||||
class TC_GAME_API AnyDeadUnitSpellTargetInRangeCheck : public AnyDeadUnitObjectInRangeCheck, public WorldObjectSpellTargetCheck
|
||||
{
|
||||
public:
|
||||
AnyDeadUnitSpellTargetInRangeCheck(Unit* searchObj, float range, SpellInfo const* spellInfo, SpellTargetCheckTypes check, SpellTargetObjectTypes objectType)
|
||||
: AnyDeadUnitObjectInRangeCheck(searchObj, range), i_spellInfo(spellInfo), i_check(searchObj, searchObj, spellInfo, check, nullptr, objectType)
|
||||
AnyDeadUnitSpellTargetInRangeCheck(WorldObject* searchObj, float range, SpellInfo const* spellInfo, SpellTargetCheckTypes check, SpellTargetObjectTypes objectType)
|
||||
: AnyDeadUnitObjectInRangeCheck(searchObj, range), WorldObjectSpellTargetCheck(searchObj, searchObj, spellInfo, check, nullptr, objectType)
|
||||
{ }
|
||||
bool operator()(Player* u);
|
||||
bool operator()(Corpse* u);
|
||||
bool operator()(Creature* u);
|
||||
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
|
||||
protected:
|
||||
SpellInfo const* i_spellInfo;
|
||||
WorldObjectSpellTargetCheck i_check;
|
||||
};
|
||||
|
||||
// WorldObject do classes
|
||||
@@ -712,24 +709,23 @@ namespace Trinity
|
||||
class GameObjectFocusCheck
|
||||
{
|
||||
public:
|
||||
GameObjectFocusCheck(Unit const* unit, uint32 focusId) : i_unit(unit), i_focusId(focusId) { }
|
||||
GameObjectFocusCheck(WorldObject const* caster, uint32 focusId) : _caster(caster), _focusId(focusId) { }
|
||||
|
||||
bool operator()(GameObject* go) const
|
||||
{
|
||||
if (go->GetGOInfo()->GetSpellFocusType() != i_focusId)
|
||||
if (go->GetGOInfo()->GetSpellFocusType() != _focusId)
|
||||
return false;
|
||||
|
||||
if (!go->isSpawned())
|
||||
return false;
|
||||
|
||||
float dist = go->GetGOInfo()->GetSpellFocusRadius() / 2.f;
|
||||
|
||||
return go->IsWithinDistInMap(i_unit, dist);
|
||||
float const dist = go->GetGOInfo()->GetSpellFocusRadius() / 2.f;
|
||||
return go->IsWithinDistInMap(_caster, dist);
|
||||
}
|
||||
|
||||
private:
|
||||
Unit const* i_unit;
|
||||
uint32 i_focusId;
|
||||
WorldObject const* _caster;
|
||||
uint32 _focusId;
|
||||
};
|
||||
|
||||
// Find the nearest Fishing hole and return true only if source object is in range of hole
|
||||
|
||||
@@ -3521,9 +3521,9 @@ bool Guild::HasAchieved(uint32 achievementId) const
|
||||
return m_achievementMgr.HasAchieved(achievementId);
|
||||
}
|
||||
|
||||
void Guild::UpdateCriteria(CriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit* unit, Player* player)
|
||||
void Guild::UpdateCriteria(CriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, WorldObject* ref, Player* player)
|
||||
{
|
||||
m_achievementMgr.UpdateCriteria(type, miscValue1, miscValue2, miscValue3, unit, player);
|
||||
m_achievementMgr.UpdateCriteria(type, miscValue1, miscValue2, miscValue3, ref, player);
|
||||
}
|
||||
|
||||
void Guild::HandleNewsSetSticky(WorldSession* session, uint32 newsId, bool sticky) const
|
||||
|
||||
@@ -841,7 +841,7 @@ class TC_GAME_API Guild
|
||||
void ResetTimes(bool weekly);
|
||||
|
||||
bool HasAchieved(uint32 achievementId) const;
|
||||
void UpdateCriteria(CriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, Unit* unit, Player* player);
|
||||
void UpdateCriteria(CriteriaTypes type, uint64 miscValue1, uint64 miscValue2, uint64 miscValue3, WorldObject* ref, Player* player);
|
||||
|
||||
protected:
|
||||
ObjectGuid::LowType m_id;
|
||||
|
||||
@@ -423,7 +423,7 @@ class TC_GAME_API Map : public GridRefManager<NGridType>
|
||||
PlayerList const& GetPlayers() const { return m_mapRefManager; }
|
||||
|
||||
//per-map script storage
|
||||
void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo> > const& scripts, uint32 id, Object* source, Object* target);
|
||||
void ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo>> const& scripts, uint32 id, Object* source, Object* target);
|
||||
void ScriptCommandStart(ScriptInfo const& script, uint32 delay, Object* source, Object* target);
|
||||
|
||||
// must called with AddToWorld
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
#include "World.h"
|
||||
|
||||
/// Put scripts in the execution queue
|
||||
void Map::ScriptsStart(ScriptMapMap const& scripts, uint32 id, Object* source, Object* target)
|
||||
void Map::ScriptsStart(std::map<uint32, std::multimap<uint32, ScriptInfo>> const& scripts, uint32 id, Object* source, Object* target)
|
||||
{
|
||||
///- Find the script map
|
||||
ScriptMapMap::const_iterator s = scripts.find(id);
|
||||
|
||||
@@ -38,21 +38,24 @@ void SpellCastLogData::Initialize(Unit const* unit)
|
||||
|
||||
void SpellCastLogData::Initialize(Spell const* spell)
|
||||
{
|
||||
Health = spell->GetCaster()->GetHealth();
|
||||
AttackPower = spell->GetCaster()->GetTotalAttackPowerValue(spell->GetCaster()->getClass() == CLASS_HUNTER ? RANGED_ATTACK : BASE_ATTACK);
|
||||
SpellPower = spell->GetCaster()->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SPELL);
|
||||
Armor = spell->GetCaster()->GetArmor();
|
||||
Powers primaryPowerType = spell->GetCaster()->GetPowerType();
|
||||
bool primaryPowerAdded = false;
|
||||
for (SpellPowerCost const& cost : spell->GetPowerCost())
|
||||
if (Unit const* unitCaster = spell->GetCaster()->ToUnit())
|
||||
{
|
||||
PowerData.emplace_back(int32(cost.Power), spell->GetCaster()->GetPower(Powers(cost.Power)), int32(cost.Amount));
|
||||
if (cost.Power == primaryPowerType)
|
||||
primaryPowerAdded = true;
|
||||
}
|
||||
Health = unitCaster->GetHealth();
|
||||
AttackPower = unitCaster->GetTotalAttackPowerValue(unitCaster->getClass() == CLASS_HUNTER ? RANGED_ATTACK : BASE_ATTACK);
|
||||
SpellPower = unitCaster->SpellBaseDamageBonusDone(SPELL_SCHOOL_MASK_SPELL);
|
||||
Armor = unitCaster->GetArmor();
|
||||
Powers primaryPowerType = unitCaster->GetPowerType();
|
||||
bool primaryPowerAdded = false;
|
||||
for (SpellPowerCost const& cost : spell->GetPowerCost())
|
||||
{
|
||||
PowerData.emplace_back(int32(cost.Power), unitCaster->GetPower(Powers(cost.Power)), int32(cost.Amount));
|
||||
if (cost.Power == primaryPowerType)
|
||||
primaryPowerAdded = true;
|
||||
}
|
||||
|
||||
if (!primaryPowerAdded)
|
||||
PowerData.insert(PowerData.begin(), SpellLogPowerData(int32(primaryPowerType), spell->GetCaster()->GetPower(primaryPowerType), 0));
|
||||
if (!primaryPowerAdded)
|
||||
PowerData.insert(PowerData.begin(), SpellLogPowerData(int32(primaryPowerType), unitCaster->GetPower(primaryPowerType), 0));
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, class U>
|
||||
|
||||
@@ -362,8 +362,6 @@ Aura* Aura::TryRefreshStackOrCreate(AuraCreateInfo& createInfo)
|
||||
|
||||
Aura* Aura::TryCreate(AuraCreateInfo& createInfo)
|
||||
{
|
||||
ASSERT(createInfo.Caster || !createInfo.CasterGUID.IsEmpty());
|
||||
|
||||
uint32 effMask = createInfo._auraEffectMask;
|
||||
if (createInfo._targetEffectMask)
|
||||
effMask = createInfo._targetEffectMask;
|
||||
@@ -377,17 +375,25 @@ Aura* Aura::TryCreate(AuraCreateInfo& createInfo)
|
||||
|
||||
Aura* Aura::Create(AuraCreateInfo& createInfo)
|
||||
{
|
||||
ASSERT(createInfo.Caster || !createInfo.CasterGUID.IsEmpty());
|
||||
|
||||
// try to get caster of aura
|
||||
if (!createInfo.CasterGUID.IsEmpty())
|
||||
{
|
||||
if (createInfo._owner->GetGUID() == createInfo.CasterGUID)
|
||||
createInfo.Caster = createInfo._owner->ToUnit();
|
||||
// world gameobjects can't own auras and they send empty casterguid
|
||||
// checked on sniffs with spell 22247
|
||||
if (createInfo.CasterGUID.IsGameObject())
|
||||
{
|
||||
createInfo.Caster = nullptr;
|
||||
createInfo.CasterGUID.Clear();
|
||||
}
|
||||
else
|
||||
createInfo.Caster = ObjectAccessor::GetUnit(*createInfo._owner, createInfo.CasterGUID);
|
||||
{
|
||||
if (createInfo._owner->GetGUID() == createInfo.CasterGUID)
|
||||
createInfo.Caster = createInfo._owner->ToUnit();
|
||||
else
|
||||
createInfo.Caster = ObjectAccessor::GetUnit(*createInfo._owner, createInfo.CasterGUID);
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (createInfo.Caster)
|
||||
createInfo.CasterGUID = createInfo.Caster->GetGUID();
|
||||
|
||||
// check if aura can be owned by owner
|
||||
@@ -440,7 +446,7 @@ Aura* Aura::Create(AuraCreateInfo& createInfo)
|
||||
}
|
||||
|
||||
Aura::Aura(AuraCreateInfo const& createInfo) :
|
||||
m_spellInfo(createInfo._spellInfo), m_castDifficulty(createInfo._castDifficulty), m_castGuid(createInfo._castId), m_casterGuid(createInfo.CasterGUID.IsEmpty() ? createInfo.Caster->GetGUID() : createInfo.CasterGUID),
|
||||
m_spellInfo(createInfo._spellInfo), m_castDifficulty(createInfo._castDifficulty), m_castGuid(createInfo._castId), m_casterGuid(createInfo.CasterGUID),
|
||||
m_castItemGuid(createInfo.CastItemGUID), m_castItemId(createInfo.CastItemId),
|
||||
m_castItemLevel(createInfo.CastItemLevel), m_spellVisual({ createInfo.Caster ? createInfo.Caster->GetCastSpellXSpellVisualId(createInfo._spellInfo) : createInfo._spellInfo->GetSpellXSpellVisualId(), 0 }),
|
||||
m_applyTime(GameTime::GetGameTime()), m_owner(createInfo._owner), m_timeCla(0), m_updateTargetMapInterval(0),
|
||||
|
||||
+690
-528
File diff suppressed because it is too large
Load Diff
@@ -275,8 +275,7 @@ class TC_GAME_API SpellCastTargets
|
||||
float GetSpeedXY() const { return m_speed * std::cos(m_pitch); }
|
||||
float GetSpeedZ() const { return m_speed * std::sin(m_pitch); }
|
||||
|
||||
void Update(Unit* caster);
|
||||
void OutDebug() const;
|
||||
void Update(WorldObject* caster);
|
||||
std::string GetTargetString() const { return m_strTarget; }
|
||||
|
||||
private:
|
||||
@@ -301,7 +300,7 @@ class TC_GAME_API SpellCastTargets
|
||||
|
||||
struct SpellValue
|
||||
{
|
||||
explicit SpellValue(SpellInfo const* proto, Unit const* caster);
|
||||
explicit SpellValue(SpellInfo const* proto, WorldObject const* caster);
|
||||
int32 EffectBasePoints[MAX_SPELL_EFFECTS];
|
||||
uint32 CustomBasePointsMask;
|
||||
uint32 MaxAffectedTargets;
|
||||
@@ -496,7 +495,7 @@ class TC_GAME_API Spell
|
||||
|
||||
typedef std::unordered_set<Aura*> UsedSpellMods;
|
||||
|
||||
Spell(Unit* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID = ObjectGuid::Empty);
|
||||
Spell(WorldObject* caster, SpellInfo const* info, TriggerCastFlags triggerFlags, ObjectGuid originalCasterGUID = ObjectGuid::Empty);
|
||||
~Spell();
|
||||
|
||||
void InitExplicitTargets(SpellCastTargets const& targets);
|
||||
@@ -520,10 +519,10 @@ class TC_GAME_API Spell
|
||||
void SelectEffectTypeImplicitTargets(uint32 effIndex);
|
||||
|
||||
uint32 GetSearcherTypeMask(SpellTargetObjectTypes objType, ConditionContainer* condList);
|
||||
template<class SEARCHER> void SearchTargets(SEARCHER& searcher, uint32 containerMask, Unit* referer, Position const* pos, float radius);
|
||||
template<class SEARCHER> void SearchTargets(SEARCHER& searcher, uint32 containerMask, WorldObject* referer, Position const* pos, float radius);
|
||||
|
||||
WorldObject* SearchNearbyTarget(float range, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList = nullptr);
|
||||
void SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, Unit* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList);
|
||||
void SearchAreaTargets(std::list<WorldObject*>& targets, float range, Position const* position, WorldObject* referer, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectionType, ConditionContainer* condList);
|
||||
void SearchChainTargets(std::list<WorldObject*>& targets, uint32 chainTargets, WorldObject* target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, ConditionContainer* condList, bool isChainHeal);
|
||||
|
||||
GameObject* SearchSpellFocus();
|
||||
@@ -565,7 +564,7 @@ class TC_GAME_API Spell
|
||||
bool CheckSpellCancelsConfuse(uint32* param1) const;
|
||||
bool CheckSpellCancelsNoActions(uint32* param1) const;
|
||||
|
||||
int32 CalculateDamage(uint8 i, Unit const* target, float* var = nullptr) const;
|
||||
int32 CalculateDamage(uint8 effIndex, Unit const* target, float* var = nullptr) const;
|
||||
|
||||
void Delayed();
|
||||
void DelayedChannel();
|
||||
@@ -685,7 +684,7 @@ class TC_GAME_API Spell
|
||||
|
||||
CurrentSpellTypes GetCurrentContainer() const;
|
||||
|
||||
Unit* GetCaster() const { return m_caster; }
|
||||
WorldObject* GetCaster() const { return m_caster; }
|
||||
Unit* GetOriginalCaster() const { return m_originalCaster; }
|
||||
SpellInfo const* GetSpellInfo() const { return m_spellInfo; }
|
||||
Difficulty GetCastDifficulty() const;
|
||||
@@ -717,7 +716,7 @@ class TC_GAME_API Spell
|
||||
void SendLoot(ObjectGuid guid, LootType loottype);
|
||||
std::pair<float, float> GetMinMaxRange(bool strict) const;
|
||||
|
||||
Unit* const m_caster;
|
||||
WorldObject* const m_caster;
|
||||
|
||||
SpellValue* const m_spellValue;
|
||||
|
||||
@@ -737,12 +736,12 @@ class TC_GAME_API Spell
|
||||
uint8 m_runesState;
|
||||
|
||||
uint8 m_delayAtDamageCount;
|
||||
bool isDelayableNoMore()
|
||||
bool IsDelayableNoMore()
|
||||
{
|
||||
if (m_delayAtDamageCount >= 2)
|
||||
return true;
|
||||
|
||||
m_delayAtDamageCount++;
|
||||
++m_delayAtDamageCount;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -770,6 +769,7 @@ class TC_GAME_API Spell
|
||||
SpellEffectHandleMode effectHandleMode;
|
||||
SpellEffectInfo const* effectInfo;
|
||||
// used in effects handlers
|
||||
Unit* unitCaster;
|
||||
UnitAura* _spellAura;
|
||||
DynObjAura* _dynObjAura;
|
||||
|
||||
@@ -912,7 +912,6 @@ class TC_GAME_API Spell
|
||||
|
||||
// effect helpers
|
||||
void SummonGuardian(uint32 i, uint32 entry, SummonPropertiesEntry const* properties, uint32 numSummons, ObjectGuid privateObjectOwner);
|
||||
void CalculateJumpSpeeds(SpellEffectInfo const* effInfo, float dist, float& speedxy, float& speedz);
|
||||
|
||||
void UpdateSpellCastDataTargets(WorldPackets::Spells::SpellCastData& data);
|
||||
void UpdateSpellCastDataAmmo(WorldPackets::Spells::SpellAmmo& data);
|
||||
@@ -948,26 +947,29 @@ namespace Trinity
|
||||
{
|
||||
struct TC_GAME_API WorldObjectSpellTargetCheck
|
||||
{
|
||||
Unit* _caster;
|
||||
Unit* _referer;
|
||||
SpellInfo const* _spellInfo;
|
||||
SpellTargetCheckTypes _targetSelectionType;
|
||||
ConditionSourceInfo* _condSrcInfo;
|
||||
ConditionContainer* _condList;
|
||||
protected:
|
||||
WorldObject* _caster;
|
||||
WorldObject* _referer;
|
||||
SpellInfo const* _spellInfo;
|
||||
SpellTargetCheckTypes _targetSelectionType;
|
||||
std::unique_ptr<ConditionSourceInfo> _condSrcInfo;
|
||||
ConditionContainer const* _condList;
|
||||
SpellTargetObjectTypes _objectType;
|
||||
|
||||
WorldObjectSpellTargetCheck(Unit* caster, Unit* referer, SpellInfo const* spellInfo,
|
||||
SpellTargetCheckTypes selectionType, ConditionContainer* condList, SpellTargetObjectTypes objectType);
|
||||
~WorldObjectSpellTargetCheck();
|
||||
bool operator()(WorldObject* target);
|
||||
WorldObjectSpellTargetCheck(WorldObject* caster, WorldObject* referer, SpellInfo const* spellInfo,
|
||||
SpellTargetCheckTypes selectionType, ConditionContainer const* condList, SpellTargetObjectTypes objectType);
|
||||
~WorldObjectSpellTargetCheck();
|
||||
|
||||
bool operator()(WorldObject* target) const;
|
||||
};
|
||||
|
||||
struct TC_GAME_API WorldObjectSpellNearbyTargetCheck : public WorldObjectSpellTargetCheck
|
||||
{
|
||||
float _range;
|
||||
Position const* _position;
|
||||
WorldObjectSpellNearbyTargetCheck(float range, Unit* caster, SpellInfo const* spellInfo,
|
||||
SpellTargetCheckTypes selectionType, ConditionContainer* condList, SpellTargetObjectTypes objectType);
|
||||
WorldObjectSpellNearbyTargetCheck(float range, WorldObject* caster, SpellInfo const* spellInfo,
|
||||
SpellTargetCheckTypes selectionType, ConditionContainer const* condList, SpellTargetObjectTypes objectType);
|
||||
|
||||
bool operator()(WorldObject* target);
|
||||
};
|
||||
|
||||
@@ -975,27 +977,30 @@ namespace Trinity
|
||||
{
|
||||
float _range;
|
||||
Position const* _position;
|
||||
WorldObjectSpellAreaTargetCheck(float range, Position const* position, Unit* caster,
|
||||
Unit* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList, SpellTargetObjectTypes objectType);
|
||||
bool operator()(WorldObject* target);
|
||||
WorldObjectSpellAreaTargetCheck(float range, Position const* position, WorldObject* caster,
|
||||
WorldObject* referer, SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList, SpellTargetObjectTypes objectType);
|
||||
|
||||
bool operator()(WorldObject* target) const;
|
||||
};
|
||||
|
||||
struct TC_GAME_API WorldObjectSpellConeTargetCheck : public WorldObjectSpellAreaTargetCheck
|
||||
{
|
||||
float _coneAngle;
|
||||
float _lineWidth;
|
||||
WorldObjectSpellConeTargetCheck(float coneAngle, float lineWidth, float range, Unit* caster,
|
||||
SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList, SpellTargetObjectTypes objectType);
|
||||
bool operator()(WorldObject* target);
|
||||
WorldObjectSpellConeTargetCheck(float coneAngle, float lineWidth, float range, WorldObject* caster,
|
||||
SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList, SpellTargetObjectTypes objectType);
|
||||
|
||||
bool operator()(WorldObject* target) const;
|
||||
};
|
||||
|
||||
struct TC_GAME_API WorldObjectSpellTrajTargetCheck : public WorldObjectSpellTargetCheck
|
||||
{
|
||||
float _range;
|
||||
Position const* _position;
|
||||
WorldObjectSpellTrajTargetCheck(float range, Position const* position, Unit* caster,
|
||||
SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList, SpellTargetObjectTypes objectType);
|
||||
bool operator()(WorldObject* target);
|
||||
WorldObjectSpellTrajTargetCheck(float range, Position const* position, WorldObject* caster,
|
||||
SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList, SpellTargetObjectTypes objectType);
|
||||
|
||||
bool operator()(WorldObject* target) const;
|
||||
};
|
||||
|
||||
struct TC_GAME_API WorldObjectSpellLineTargetCheck : public WorldObjectSpellAreaTargetCheck
|
||||
@@ -1003,12 +1008,13 @@ namespace Trinity
|
||||
Position const* _srcPosition;
|
||||
Position const* _dstPosition;
|
||||
float _lineWidth;
|
||||
WorldObjectSpellLineTargetCheck(Position const* srcPosition, Position const* dstPosition, float lineWidth, float range, Unit* caster,
|
||||
SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer* condList, SpellTargetObjectTypes objectType);
|
||||
bool operator()(WorldObject* target);
|
||||
WorldObjectSpellLineTargetCheck(Position const* srcPosition, Position const* dstPosition, float lineWidth, float range, WorldObject* caster,
|
||||
SpellInfo const* spellInfo, SpellTargetCheckTypes selectionType, ConditionContainer const* condList, SpellTargetObjectTypes objectType);
|
||||
|
||||
bool operator()(WorldObject* target) const;
|
||||
};
|
||||
}
|
||||
|
||||
typedef void(Spell::*pEffect)(SpellEffIndex effIndex);
|
||||
typedef void(Spell::*SpellEffectHandlerFn)(SpellEffIndex effIndex);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -279,7 +279,7 @@ struct TC_GAME_API CastSpellExtraArgs
|
||||
struct
|
||||
{
|
||||
friend struct CastSpellExtraArgs;
|
||||
friend class Unit;
|
||||
friend class WorldObject;
|
||||
|
||||
private:
|
||||
void AddMod(SpellValueMod mod, int32 val) { data.push_back({ mod, val }); }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -452,7 +452,7 @@ bool SpellEffectInfo::IsUnitOwnedAuraEffect() const
|
||||
return IsAreaAuraEffect() || Effect == SPELL_EFFECT_APPLY_AURA || Effect == SPELL_EFFECT_APPLY_AURA_ON_PET;
|
||||
}
|
||||
|
||||
int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, uint32 castItemId /*= 0*/, int32 itemLevel /*= -1*/) const
|
||||
int32 SpellEffectInfo::CalcValue(WorldObject const* caster /*= nullptr*/, int32 const* bp /*= nullptr*/, Unit const* target /*= nullptr*/, float* variance /*= nullptr*/, uint32 castItemId /*= 0*/, int32 itemLevel /*= -1*/) const
|
||||
{
|
||||
float basePointsPerLevel = RealPointsPerLevel;
|
||||
// TODO: this needs to be a float, not rounded
|
||||
@@ -460,6 +460,10 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const*
|
||||
float value = bp ? *bp : basePoints;
|
||||
float comboDamage = PointsPerResource;
|
||||
|
||||
Unit const* casterUnit = nullptr;
|
||||
if (caster)
|
||||
casterUnit = caster->ToUnit();
|
||||
|
||||
if (Scaling.Variance)
|
||||
{
|
||||
float delta = fabs(Scaling.Variance * 0.5f);
|
||||
@@ -478,9 +482,9 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const*
|
||||
}
|
||||
else if (GetScalingExpectedStat() == ExpectedStatType::None)
|
||||
{
|
||||
if (caster && basePointsPerLevel != 0.0f)
|
||||
if (casterUnit && basePointsPerLevel != 0.0f)
|
||||
{
|
||||
int32 level = int32(caster->getLevel());
|
||||
int32 level = int32(casterUnit->getLevel());
|
||||
if (level > int32(_spellInfo->MaxLevel) && _spellInfo->MaxLevel > 0)
|
||||
level = int32(_spellInfo->MaxLevel);
|
||||
|
||||
@@ -493,28 +497,29 @@ int32 SpellEffectInfo::CalcValue(Unit const* caster /*= nullptr*/, int32 const*
|
||||
}
|
||||
|
||||
// random damage
|
||||
if (caster)
|
||||
if (casterUnit)
|
||||
{
|
||||
// bonus amount from combo points
|
||||
if (caster->m_playerMovingMe && comboDamage)
|
||||
if (uint32 comboPoints = caster->m_playerMovingMe->GetComboPoints())
|
||||
if (comboDamage)
|
||||
if (uint32 comboPoints = casterUnit->GetComboPoints())
|
||||
value += comboDamage * comboPoints;
|
||||
|
||||
value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value);
|
||||
}
|
||||
|
||||
if (caster)
|
||||
value = caster->ApplyEffectModifiers(_spellInfo, EffectIndex, value);
|
||||
|
||||
return int32(round(value));
|
||||
}
|
||||
|
||||
int32 SpellEffectInfo::CalcBaseValue(Unit const* caster, Unit const* target, uint32 itemId, int32 itemLevel) const
|
||||
int32 SpellEffectInfo::CalcBaseValue(WorldObject const* caster, Unit const* target, uint32 itemId, int32 itemLevel) const
|
||||
{
|
||||
if (Scaling.Coefficient != 0.0f)
|
||||
{
|
||||
uint32 level = _spellInfo->SpellLevel;
|
||||
if (target && _spellInfo->IsPositiveEffect(EffectIndex) && (Effect == SPELL_EFFECT_APPLY_AURA))
|
||||
level = target->getLevel();
|
||||
else if (caster)
|
||||
level = caster->getLevel();
|
||||
else if (caster && caster->IsUnit())
|
||||
level = caster->ToUnit()->getLevel();
|
||||
|
||||
if (_spellInfo->BaseLevel && !_spellInfo->HasAttribute(SPELL_ATTR11_SCALES_WITH_ITEM_LEVEL) && _spellInfo->HasAttribute(SPELL_ATTR10_USE_SPELL_BASE_LEVEL_FOR_SCALING))
|
||||
level = _spellInfo->BaseLevel;
|
||||
@@ -591,7 +596,7 @@ int32 SpellEffectInfo::CalcBaseValue(Unit const* caster, Unit const* target, uin
|
||||
if (ContentTuningEntry const* contentTuning = sContentTuningStore.LookupEntry(contentTuningId))
|
||||
expansion = contentTuning->ExpansionID;
|
||||
|
||||
int32 level = caster ? int32(caster->getLevel()) : 1;
|
||||
int32 level = caster && caster->IsUnit() ? int32(caster->ToUnit()->getLevel()) : 1;
|
||||
value = sDB2Manager.EvaluateExpectedStat(stat, level, expansion, 0, CLASS_NONE) * BasePoints / 100.0f;
|
||||
}
|
||||
|
||||
@@ -599,7 +604,7 @@ int32 SpellEffectInfo::CalcBaseValue(Unit const* caster, Unit const* target, uin
|
||||
}
|
||||
}
|
||||
|
||||
float SpellEffectInfo::CalcValueMultiplier(Unit* caster, Spell* spell) const
|
||||
float SpellEffectInfo::CalcValueMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
|
||||
{
|
||||
float multiplier = Amplitude;
|
||||
if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
|
||||
@@ -607,7 +612,7 @@ float SpellEffectInfo::CalcValueMultiplier(Unit* caster, Spell* spell) const
|
||||
return multiplier;
|
||||
}
|
||||
|
||||
float SpellEffectInfo::CalcDamageMultiplier(Unit* caster, Spell* spell) const
|
||||
float SpellEffectInfo::CalcDamageMultiplier(WorldObject* caster, Spell* spell /*= nullptr*/) const
|
||||
{
|
||||
float multiplierPercent = ChainAmplitude * 100.0f;
|
||||
if (Player* modOwner = (caster ? caster->GetSpellModOwner() : nullptr))
|
||||
@@ -625,7 +630,7 @@ bool SpellEffectInfo::HasMaxRadius() const
|
||||
return MaxRadiusEntry != nullptr;
|
||||
}
|
||||
|
||||
float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const
|
||||
float SpellEffectInfo::CalcRadius(WorldObject* caster /*= nullptr*/, Spell* spell /*= nullptr*/) const
|
||||
{
|
||||
const SpellRadiusEntry* entry = RadiusEntry;
|
||||
if (!HasRadius() && HasMaxRadius())
|
||||
@@ -642,8 +647,11 @@ float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const
|
||||
|
||||
if (caster)
|
||||
{
|
||||
radius += entry->RadiusPerLevel * caster->getLevel();
|
||||
if (Unit* casterUnit = caster->ToUnit())
|
||||
radius += entry->RadiusPerLevel * casterUnit->getLevel();
|
||||
|
||||
radius = std::min(radius, entry->RadiusMax);
|
||||
|
||||
if (Player* modOwner = caster->GetSpellModOwner())
|
||||
modOwner->ApplySpellMod(_spellInfo, SpellModOp::Radius, radius, spell);
|
||||
}
|
||||
@@ -1354,13 +1362,13 @@ bool SpellInfo::HasTargetType(::Targets target) const
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SpellInfo::CanBeInterrupted(Unit* interruptCaster, Unit* interruptTarget) const
|
||||
bool SpellInfo::CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget) const
|
||||
{
|
||||
return HasAttribute(SPELL_ATTR7_CAN_ALWAYS_BE_INTERRUPTED)
|
||||
|| HasChannelInterruptFlag(SpellAuraInterruptFlags::Damage | SpellAuraInterruptFlags::EnteringCombat)
|
||||
|| (interruptTarget->IsPlayer() && InterruptFlags.HasFlag(SpellInterruptFlags::DamageCancelsPlayerOnly))
|
||||
|| InterruptFlags.HasFlag(SpellInterruptFlags::DamageCancels)
|
||||
|| interruptCaster->HasAuraTypeWithMiscvalue(SPELL_AURA_ALLOW_INTERRUPT_SPELL, Id)
|
||||
|| (interruptCaster->IsUnit() && interruptCaster->ToUnit()->HasAuraTypeWithMiscvalue(SPELL_AURA_ALLOW_INTERRUPT_SPELL, Id))
|
||||
|| (!(interruptTarget->GetMechanicImmunityMask() & (1 << MECHANIC_INTERRUPT))
|
||||
&& !interruptTarget->HasAuraTypeWithAffectMask(SPELL_AURA_PREVENT_INTERRUPT, this)
|
||||
&& PreventionType & SPELL_PREVENTION_TYPE_SILENCE);
|
||||
@@ -2086,7 +2094,7 @@ SpellCastResult SpellInfo::CheckLocation(uint32 map_id, uint32 zone_id, uint32 a
|
||||
return SPELL_CAST_OK;
|
||||
}
|
||||
|
||||
SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* target, bool implicit) const
|
||||
SpellCastResult SpellInfo::CheckTarget(WorldObject const* caster, WorldObject const* target, bool implicit /*= true*/) const
|
||||
{
|
||||
if (HasAttribute(SPELL_ATTR1_CANT_TARGET_SELF) && caster == target)
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
@@ -2188,7 +2196,7 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
|
||||
}
|
||||
|
||||
// check GM mode and GM invisibility - only for player casts (npc casts are controlled by AI) and negative spells
|
||||
if (unitTarget != caster && (caster->IsControlledByPlayer() || !IsPositive()) && unitTarget->GetTypeId() == TYPEID_PLAYER)
|
||||
if (unitTarget != caster && (caster->GetAffectingPlayer() || !IsPositive()) && unitTarget->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
if (!unitTarget->ToPlayer()->IsVisible())
|
||||
return SPELL_FAILED_BM_OR_INVISGOD;
|
||||
@@ -2208,13 +2216,16 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
|
||||
him, because it would be it's passenger, there's no such case where this gets to fail legitimacy, this problem
|
||||
cannot be solved from within the check in other way since target type cannot be called for the spell currently
|
||||
Spell examples: [ID - 52864 Devour Water, ID - 52862 Devour Wind, ID - 49370 Wyrmrest Defender: Destabilize Azure Dragonshrine Effect] */
|
||||
if (!caster->IsVehicle() && !(caster->GetCharmerOrOwner() == target))
|
||||
if (Unit const* unitCaster = caster->ToUnit())
|
||||
{
|
||||
if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, caster))
|
||||
return SPELL_FAILED_TARGET_AURASTATE;
|
||||
if (!unitCaster->IsVehicle() && !(unitCaster->GetCharmerOrOwner() == target))
|
||||
{
|
||||
if (TargetAuraState && !unitTarget->HasAuraState(AuraStateType(TargetAuraState), this, unitCaster))
|
||||
return SPELL_FAILED_TARGET_AURASTATE;
|
||||
|
||||
if (ExcludeTargetAuraState && unitTarget->HasAuraState(AuraStateType(ExcludeTargetAuraState), this, caster))
|
||||
return SPELL_FAILED_TARGET_AURASTATE;
|
||||
if (ExcludeTargetAuraState && unitTarget->HasAuraState(AuraStateType(ExcludeTargetAuraState), this, unitCaster))
|
||||
return SPELL_FAILED_TARGET_AURASTATE;
|
||||
}
|
||||
}
|
||||
|
||||
if (TargetAuraSpell && !unitTarget->HasAura(TargetAuraSpell))
|
||||
@@ -2237,7 +2248,7 @@ SpellCastResult SpellInfo::CheckTarget(Unit const* caster, WorldObject const* ta
|
||||
return SPELL_CAST_OK;
|
||||
}
|
||||
|
||||
SpellCastResult SpellInfo::CheckExplicitTarget(Unit const* caster, WorldObject const* target, Item const* itemTarget) const
|
||||
SpellCastResult SpellInfo::CheckExplicitTarget(WorldObject const* caster, WorldObject const* target, Item const* itemTarget /*= nullptr*/) const
|
||||
{
|
||||
uint32 neededTargets = GetExplicitTargetMask();
|
||||
if (!target)
|
||||
@@ -2252,19 +2263,20 @@ SpellCastResult SpellInfo::CheckExplicitTarget(Unit const* caster, WorldObject c
|
||||
{
|
||||
if (neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT_ALLY | TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_MINIPET | TARGET_FLAG_UNIT_PASSENGER))
|
||||
{
|
||||
Unit const* unitCaster = caster->ToUnit();
|
||||
if (neededTargets & TARGET_FLAG_UNIT_ENEMY)
|
||||
if (caster->IsValidAttackTarget(unitTarget, this))
|
||||
return SPELL_CAST_OK;
|
||||
if (neededTargets & TARGET_FLAG_UNIT_ALLY
|
||||
|| (neededTargets & TARGET_FLAG_UNIT_PARTY && caster->IsInPartyWith(unitTarget))
|
||||
|| (neededTargets & TARGET_FLAG_UNIT_RAID && caster->IsInRaidWith(unitTarget)))
|
||||
if ((neededTargets & TARGET_FLAG_UNIT_ALLY)
|
||||
|| ((neededTargets & TARGET_FLAG_UNIT_PARTY) && unitCaster && unitCaster->IsInPartyWith(unitTarget))
|
||||
|| ((neededTargets & TARGET_FLAG_UNIT_RAID) && unitCaster && unitCaster->IsInRaidWith(unitTarget)))
|
||||
if (caster->IsValidAssistTarget(unitTarget, this))
|
||||
return SPELL_CAST_OK;
|
||||
if (neededTargets & TARGET_FLAG_UNIT_MINIPET)
|
||||
if (unitTarget->GetGUID() == caster->GetCritterGUID())
|
||||
if ((neededTargets & TARGET_FLAG_UNIT_MINIPET) && unitCaster)
|
||||
if (unitTarget->GetGUID() == unitCaster->GetCritterGUID())
|
||||
return SPELL_CAST_OK;
|
||||
if (neededTargets & TARGET_FLAG_UNIT_PASSENGER)
|
||||
if (unitTarget->IsOnVehicle(caster))
|
||||
if ((neededTargets & TARGET_FLAG_UNIT_PASSENGER) && unitCaster)
|
||||
if (unitTarget->IsOnVehicle(unitCaster))
|
||||
return SPELL_CAST_OK;
|
||||
return SPELL_FAILED_BAD_TARGETS;
|
||||
}
|
||||
@@ -3695,14 +3707,14 @@ uint32 SpellInfo::GetAllowedMechanicMask() const
|
||||
return _allowedMechanicMask;
|
||||
}
|
||||
|
||||
float SpellInfo::GetMinRange(bool positive) const
|
||||
float SpellInfo::GetMinRange(bool positive /*= false*/) const
|
||||
{
|
||||
if (!RangeEntry)
|
||||
return 0.0f;
|
||||
return RangeEntry->RangeMin[positive ? 1 : 0];
|
||||
}
|
||||
|
||||
float SpellInfo::GetMaxRange(bool positive, Unit* caster, Spell* spell) const
|
||||
float SpellInfo::GetMaxRange(bool positive /*= false*/, WorldObject* caster /*= nullptr*/, Spell* spell /*= nullptr*/) const
|
||||
{
|
||||
if (!RangeEntry)
|
||||
return 0.0f;
|
||||
@@ -3714,7 +3726,7 @@ float SpellInfo::GetMaxRange(bool positive, Unit* caster, Spell* spell) const
|
||||
return range;
|
||||
}
|
||||
|
||||
int32 SpellInfo::CalcDuration(Unit* caster /*= nullptr*/) const
|
||||
int32 SpellInfo::CalcDuration(WorldObject const* caster /*= nullptr*/) const
|
||||
{
|
||||
int32 duration = GetDuration();
|
||||
|
||||
@@ -3802,8 +3814,13 @@ uint32 SpellInfo::GetRecoveryTime() const
|
||||
return RecoveryTime > CategoryRecoveryTime ? RecoveryTime : CategoryRecoveryTime;
|
||||
}
|
||||
|
||||
Optional<SpellPowerCost> SpellInfo::CalcPowerCost(Powers powerType, bool optionalCost, Unit const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
|
||||
Optional<SpellPowerCost> SpellInfo::CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
|
||||
{
|
||||
// gameobject casts don't use power
|
||||
Unit const* unitCaster = caster->ToUnit();
|
||||
if (!unitCaster)
|
||||
return {};
|
||||
|
||||
auto itr = std::find_if(PowerCosts.cbegin(), PowerCosts.cend(), [powerType](SpellPowerEntry const* spellPowerEntry)
|
||||
{
|
||||
return spellPowerEntry && spellPowerEntry->PowerType == powerType;
|
||||
@@ -3814,9 +3831,14 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(Powers powerType, bool optiona
|
||||
return CalcPowerCost(*itr, optionalCost, caster, schoolMask, spell);
|
||||
}
|
||||
|
||||
Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power, bool optionalCost, Unit const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
|
||||
Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell /*= nullptr*/) const
|
||||
{
|
||||
if (power->RequiredAuraSpellID && !caster->HasAura(power->RequiredAuraSpellID))
|
||||
// gameobject casts don't use power
|
||||
Unit const* unitCaster = caster->ToUnit();
|
||||
if (!unitCaster)
|
||||
return {};
|
||||
|
||||
if (power->RequiredAuraSpellID && !unitCaster->HasAura(power->RequiredAuraSpellID))
|
||||
return {};
|
||||
|
||||
// Spell drain all exist power on cast (Only paladin lay of Hands)
|
||||
@@ -3827,7 +3849,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
{
|
||||
SpellPowerCost cost;
|
||||
cost.Power = POWER_HEALTH;
|
||||
cost.Amount = caster->GetHealth();
|
||||
cost.Amount = unitCaster->GetHealth();
|
||||
return cost;
|
||||
}
|
||||
// Else drain all power
|
||||
@@ -3835,7 +3857,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
{
|
||||
SpellPowerCost cost;
|
||||
cost.Power = Powers(power->PowerType);
|
||||
cost.Amount = caster->GetPower(cost.Power);
|
||||
cost.Amount = unitCaster->GetPower(cost.Power);
|
||||
return cost;
|
||||
}
|
||||
|
||||
@@ -3856,12 +3878,12 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
// health as power used
|
||||
case POWER_HEALTH:
|
||||
if (G3D::fuzzyEq(power->PowerCostPct, 0.0f))
|
||||
powerCost += int32(CalculatePct(caster->GetMaxHealth(), power->PowerCostMaxPct));
|
||||
powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostMaxPct));
|
||||
else
|
||||
powerCost += int32(CalculatePct(caster->GetMaxHealth(), power->PowerCostPct));
|
||||
powerCost += int32(CalculatePct(unitCaster->GetMaxHealth(), power->PowerCostPct));
|
||||
break;
|
||||
case POWER_MANA:
|
||||
powerCost += int32(CalculatePct(caster->GetCreateMana(), power->PowerCostPct));
|
||||
powerCost += int32(CalculatePct(unitCaster->GetCreateMana(), power->PowerCostPct));
|
||||
break;
|
||||
case POWER_ALTERNATE_POWER:
|
||||
TC_LOG_ERROR("spells", "SpellInfo::CalcPowerCost: Unknown power type '%d' in spell %d", power->PowerType, Id);
|
||||
@@ -3883,7 +3905,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
else
|
||||
{
|
||||
powerCost = int32(power->OptionalCost);
|
||||
powerCost += caster->GetTotalAuraModifier(SPELL_AURA_MOD_ADDITIONAL_POWER_COST, [this, power](AuraEffect const* aurEff) -> bool
|
||||
powerCost += unitCaster->GetTotalAuraModifier(SPELL_AURA_MOD_ADDITIONAL_POWER_COST, [this, power](AuraEffect const* aurEff) -> bool
|
||||
{
|
||||
return aurEff->GetMiscValue() == power->PowerType
|
||||
&& aurEff->IsAffectingSpell(this);
|
||||
@@ -3896,7 +3918,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
if (HasAttribute(SPELL_ATTR4_SPELL_VS_EXTEND_COST))
|
||||
{
|
||||
uint32 speed = 0;
|
||||
if (SpellShapeshiftFormEntry const* ss = sSpellShapeshiftFormStore.LookupEntry(caster->GetShapeshiftForm()))
|
||||
if (SpellShapeshiftFormEntry const* ss = sSpellShapeshiftFormStore.LookupEntry(unitCaster->GetShapeshiftForm()))
|
||||
speed = ss->CombatRoundTime;
|
||||
else
|
||||
{
|
||||
@@ -3904,7 +3926,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
if (!HasAttribute(SPELL_ATTR3_MAIN_HAND) && HasAttribute(SPELL_ATTR3_REQ_OFFHAND))
|
||||
slot = OFF_ATTACK;
|
||||
|
||||
speed = caster->GetBaseAttackTime(slot);
|
||||
speed = unitCaster->GetBaseAttackTime(slot);
|
||||
}
|
||||
|
||||
powerCost += speed / 100;
|
||||
@@ -3915,7 +3937,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
if (!optionalCost)
|
||||
{
|
||||
// Flat mod from caster auras by spell school and power type
|
||||
for (AuraEffect const* aura : caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL))
|
||||
for (AuraEffect const* aura : unitCaster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL))
|
||||
{
|
||||
if (!(aura->GetMiscValue() & schoolMask))
|
||||
continue;
|
||||
@@ -3928,7 +3950,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
}
|
||||
|
||||
// PCT mod from user auras by spell school and power type
|
||||
for (auto schoolCostPct : caster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT))
|
||||
for (auto schoolCostPct : unitCaster->GetAuraEffectsByType(SPELL_AURA_MOD_POWER_COST_SCHOOL_PCT))
|
||||
{
|
||||
if (!(schoolCostPct->GetMiscValue() & schoolMask))
|
||||
continue;
|
||||
@@ -3941,7 +3963,7 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
}
|
||||
|
||||
// Apply cost mod by spell
|
||||
if (Player* modOwner = caster->GetSpellModOwner())
|
||||
if (Player* modOwner = unitCaster->GetSpellModOwner())
|
||||
{
|
||||
Optional<SpellModOp> mod;
|
||||
switch (power->OrderIndex)
|
||||
@@ -3974,19 +3996,19 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
}
|
||||
}
|
||||
|
||||
if (!caster->IsControlledByPlayer() && G3D::fuzzyEq(power->PowerCostPct, 0.0f) && SpellLevel && power->PowerType == POWER_MANA)
|
||||
if (!unitCaster->IsControlledByPlayer() && G3D::fuzzyEq(power->PowerCostPct, 0.0f) && SpellLevel && power->PowerType == POWER_MANA)
|
||||
{
|
||||
if (HasAttribute(SPELL_ATTR0_LEVEL_DAMAGE_CALCULATION))
|
||||
{
|
||||
GtNpcManaCostScalerEntry const* spellScaler = sNpcManaCostScalerGameTable.GetRow(SpellLevel);
|
||||
GtNpcManaCostScalerEntry const* casterScaler = sNpcManaCostScalerGameTable.GetRow(caster->getLevel());
|
||||
GtNpcManaCostScalerEntry const* casterScaler = sNpcManaCostScalerGameTable.GetRow(unitCaster->getLevel());
|
||||
if (spellScaler && casterScaler)
|
||||
powerCost *= casterScaler->Scaler / spellScaler->Scaler;
|
||||
}
|
||||
}
|
||||
|
||||
if (power->PowerType == POWER_MANA)
|
||||
powerCost = float(powerCost) * (1.0f + caster->m_unitData->ManaCostMultiplier);
|
||||
powerCost = float(powerCost) * (1.0f + unitCaster->m_unitData->ManaCostMultiplier);
|
||||
|
||||
// power cost cannot become negative if initially positive
|
||||
if (initiallyNegative != (powerCost < 0))
|
||||
@@ -3998,41 +4020,44 @@ Optional<SpellPowerCost> SpellInfo::CalcPowerCost(SpellPowerEntry const* power,
|
||||
return cost;
|
||||
}
|
||||
|
||||
std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask, Spell* spell) const
|
||||
std::vector<SpellPowerCost> SpellInfo::CalcPowerCost(WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell) const
|
||||
{
|
||||
std::vector<SpellPowerCost> costs;
|
||||
costs.reserve(MAX_POWERS_PER_SPELL);
|
||||
|
||||
auto getOrCreatePowerCost = [&](Powers powerType) -> SpellPowerCost&
|
||||
if (caster->IsUnit())
|
||||
{
|
||||
auto itr = std::find_if(costs.begin(), costs.end(), [powerType](SpellPowerCost const& cost)
|
||||
costs.reserve(MAX_POWERS_PER_SPELL);
|
||||
|
||||
auto getOrCreatePowerCost = [&](Powers powerType) -> SpellPowerCost&
|
||||
{
|
||||
return cost.Power == powerType;
|
||||
});
|
||||
if (itr != costs.end())
|
||||
return *itr;
|
||||
auto itr = std::find_if(costs.begin(), costs.end(), [powerType](SpellPowerCost const& cost)
|
||||
{
|
||||
return cost.Power == powerType;
|
||||
});
|
||||
if (itr != costs.end())
|
||||
return *itr;
|
||||
|
||||
SpellPowerCost cost;
|
||||
cost.Power = powerType;
|
||||
cost.Amount = 0;
|
||||
costs.push_back(cost);
|
||||
return costs.back();
|
||||
};
|
||||
SpellPowerCost cost;
|
||||
cost.Power = powerType;
|
||||
cost.Amount = 0;
|
||||
costs.push_back(cost);
|
||||
return costs.back();
|
||||
};
|
||||
|
||||
for (SpellPowerEntry const* power : PowerCosts)
|
||||
{
|
||||
if (!power)
|
||||
continue;
|
||||
|
||||
if (Optional<SpellPowerCost> cost = CalcPowerCost(power, false, caster, schoolMask, spell))
|
||||
getOrCreatePowerCost(cost->Power).Amount += cost->Amount;
|
||||
|
||||
if (Optional<SpellPowerCost> optionalCost = CalcPowerCost(power, true, caster, schoolMask, spell))
|
||||
for (SpellPowerEntry const* power : PowerCosts)
|
||||
{
|
||||
SpellPowerCost& cost = getOrCreatePowerCost(optionalCost->Power);
|
||||
int32 remainingPower = caster->GetPower(optionalCost->Power) - cost.Amount;
|
||||
if (remainingPower > 0)
|
||||
cost.Amount += std::min(optionalCost->Amount, remainingPower);
|
||||
if (!power)
|
||||
continue;
|
||||
|
||||
if (Optional<SpellPowerCost> cost = CalcPowerCost(power, false, caster, schoolMask, spell))
|
||||
getOrCreatePowerCost(cost->Power).Amount += cost->Amount;
|
||||
|
||||
if (Optional<SpellPowerCost> optionalCost = CalcPowerCost(power, true, caster, schoolMask, spell))
|
||||
{
|
||||
SpellPowerCost& cost = getOrCreatePowerCost(optionalCost->Power);
|
||||
int32 remainingPower = caster->ToUnit()->GetPower(optionalCost->Power) - cost.Amount;
|
||||
if (remainingPower > 0)
|
||||
cost.Amount += std::min(optionalCost->Amount, remainingPower);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4266,7 +4291,7 @@ bool SpellInfo::IsHighRankOf(SpellInfo const* spellInfo) const
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 SpellInfo::GetSpellXSpellVisualId(Unit const* caster /*= nullptr*/) const
|
||||
uint32 SpellInfo::GetSpellXSpellVisualId(WorldObject const* caster /*= nullptr*/) const
|
||||
{
|
||||
for (SpellXSpellVisualEntry const* visual : _visuals)
|
||||
{
|
||||
@@ -4278,7 +4303,7 @@ uint32 SpellInfo::GetSpellXSpellVisualId(Unit const* caster /*= nullptr*/) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32 SpellInfo::GetSpellVisual(Unit const* caster /*= nullptr*/) const
|
||||
uint32 SpellInfo::GetSpellVisual(WorldObject const* caster /*= nullptr*/) const
|
||||
{
|
||||
if (SpellXSpellVisualEntry const* visual = sSpellXSpellVisualStore.LookupEntry(GetSpellXSpellVisualId(caster)))
|
||||
{
|
||||
|
||||
@@ -314,14 +314,14 @@ public:
|
||||
bool IsAreaAuraEffect() const;
|
||||
bool IsUnitOwnedAuraEffect() const;
|
||||
|
||||
int32 CalcValue(Unit const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr, float* variance = nullptr, uint32 castItemId = 0, int32 itemLevel = -1) const;
|
||||
int32 CalcBaseValue(Unit const* caster, Unit const* target, uint32 itemId, int32 itemLevel) const;
|
||||
float CalcValueMultiplier(Unit* caster, Spell* spell = nullptr) const;
|
||||
float CalcDamageMultiplier(Unit* caster, Spell* spell = nullptr) const;
|
||||
int32 CalcValue(WorldObject const* caster = nullptr, int32 const* basePoints = nullptr, Unit const* target = nullptr, float* variance = nullptr, uint32 castItemId = 0, int32 itemLevel = -1) const;
|
||||
int32 CalcBaseValue(WorldObject const* caster, Unit const* target, uint32 itemId, int32 itemLevel) const;
|
||||
float CalcValueMultiplier(WorldObject* caster, Spell* spell = nullptr) const;
|
||||
float CalcDamageMultiplier(WorldObject* caster, Spell* spell = nullptr) const;
|
||||
|
||||
bool HasRadius() const;
|
||||
bool HasMaxRadius() const;
|
||||
float CalcRadius(Unit* caster = nullptr, Spell* = nullptr) const;
|
||||
float CalcRadius(WorldObject* caster = nullptr, Spell* = nullptr) const;
|
||||
|
||||
uint32 GetProvidedTargetMask() const;
|
||||
uint32 GetMissingTargetMask(bool srcSet = false, bool destSet = false, uint32 mask = 0) const;
|
||||
@@ -500,7 +500,7 @@ class TC_GAME_API SpellInfo
|
||||
bool HasAttribute(SpellAttr14 attribute) const { return !!(AttributesEx14 & attribute); }
|
||||
bool HasAttribute(SpellCustomAttributes customAttribute) const { return !!(AttributesCu & customAttribute); }
|
||||
|
||||
bool CanBeInterrupted(Unit* interruptCaster, Unit* interruptTarget) const;
|
||||
bool CanBeInterrupted(WorldObject const* interruptCaster, Unit const* interruptTarget) const;
|
||||
|
||||
bool HasAnyAuraInterruptFlag() const;
|
||||
bool HasAuraInterruptFlag(SpellAuraInterruptFlags flag) const { return AuraInterruptFlags.HasFlag(flag); }
|
||||
@@ -564,8 +564,8 @@ class TC_GAME_API SpellInfo
|
||||
|
||||
SpellCastResult CheckShapeshift(uint32 form) const;
|
||||
SpellCastResult CheckLocation(uint32 map_id, uint32 zone_id, uint32 area_id, Player const* player = nullptr) const;
|
||||
SpellCastResult CheckTarget(Unit const* caster, WorldObject const* target, bool implicit = true) const;
|
||||
SpellCastResult CheckExplicitTarget(Unit const* caster, WorldObject const* target, Item const* itemTarget = nullptr) const;
|
||||
SpellCastResult CheckTarget(WorldObject const* caster, WorldObject const* target, bool implicit = true) const;
|
||||
SpellCastResult CheckExplicitTarget(WorldObject const* caster, WorldObject const* target, Item const* itemTarget = nullptr) const;
|
||||
SpellCastResult CheckVehicle(Unit const* caster) const;
|
||||
bool CheckTargetCreatureType(Unit const* target) const;
|
||||
|
||||
@@ -583,9 +583,9 @@ class TC_GAME_API SpellInfo
|
||||
SpellSpecificType GetSpellSpecific() const;
|
||||
|
||||
float GetMinRange(bool positive = false) const;
|
||||
float GetMaxRange(bool positive = false, Unit* caster = nullptr, Spell* spell = nullptr) const;
|
||||
float GetMaxRange(bool positive = false, WorldObject* caster = nullptr, Spell* spell = nullptr) const;
|
||||
|
||||
int32 CalcDuration(Unit* caster = nullptr) const;
|
||||
int32 CalcDuration(WorldObject const* caster = nullptr) const;
|
||||
int32 GetDuration() const;
|
||||
int32 GetMaxDuration() const;
|
||||
|
||||
@@ -594,9 +594,9 @@ class TC_GAME_API SpellInfo
|
||||
uint32 CalcCastTime(Spell* spell = nullptr) const;
|
||||
uint32 GetRecoveryTime() const;
|
||||
|
||||
Optional<SpellPowerCost> CalcPowerCost(Powers powerType, bool optionalCost, Unit const* caster, SpellSchoolMask schoolMask, Spell* spell = nullptr) const;
|
||||
Optional<SpellPowerCost> CalcPowerCost(SpellPowerEntry const* power, bool optionalCost, Unit const* caster, SpellSchoolMask schoolMask, Spell* spell = nullptr) const;
|
||||
std::vector<SpellPowerCost> CalcPowerCost(Unit const* caster, SpellSchoolMask schoolMask, Spell* spell = nullptr) const;
|
||||
Optional<SpellPowerCost> CalcPowerCost(Powers powerType, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell = nullptr) const;
|
||||
Optional<SpellPowerCost> CalcPowerCost(SpellPowerEntry const* power, bool optionalCost, WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell = nullptr) const;
|
||||
std::vector<SpellPowerCost> CalcPowerCost(WorldObject const* caster, SpellSchoolMask schoolMask, Spell* spell = nullptr) const;
|
||||
|
||||
float CalcProcPPM(Unit* caster, int32 itemLevel) const;
|
||||
|
||||
@@ -611,8 +611,8 @@ class TC_GAME_API SpellInfo
|
||||
bool IsDifferentRankOf(SpellInfo const* spellInfo) const;
|
||||
bool IsHighRankOf(SpellInfo const* spellInfo) const;
|
||||
|
||||
uint32 GetSpellXSpellVisualId(Unit const* caster = nullptr) const;
|
||||
uint32 GetSpellVisual(Unit const* caster = nullptr) const;
|
||||
uint32 GetSpellXSpellVisualId(WorldObject const* caster = nullptr) const;
|
||||
uint32 GetSpellVisual(WorldObject const* caster = nullptr) const;
|
||||
|
||||
SpellEffectInfoVector const& GetEffects() const { return _effects; }
|
||||
SpellEffectInfo const* GetEffect(uint32 index) const { return index < _effects.size() ? _effects[index] : nullptr; }
|
||||
|
||||
@@ -467,12 +467,17 @@ bool SpellScript::IsInEffectHook() const
|
||||
|
||||
Unit* SpellScript::GetCaster() const
|
||||
{
|
||||
return m_spell->GetCaster();
|
||||
return m_spell->GetCaster()->ToUnit();
|
||||
}
|
||||
|
||||
GameObject* SpellScript::GetGObjCaster() const
|
||||
{
|
||||
return m_spell->GetCaster()->ToGameObject();
|
||||
}
|
||||
|
||||
Unit* SpellScript::GetOriginalCaster() const
|
||||
{
|
||||
return m_spell->GetOriginalCaster();
|
||||
return m_spell->GetOriginalCaster();
|
||||
}
|
||||
|
||||
SpellInfo const* SpellScript::GetSpellInfo() const
|
||||
@@ -1161,7 +1166,16 @@ ObjectGuid AuraScript::GetCasterGUID() const
|
||||
|
||||
Unit* AuraScript::GetCaster() const
|
||||
{
|
||||
return m_aura->GetCaster();
|
||||
if (WorldObject* caster = m_aura->GetCaster())
|
||||
return caster->ToUnit();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
GameObject* AuraScript::GetGObjCaster() const
|
||||
{
|
||||
if (WorldObject* caster = m_aura->GetCaster())
|
||||
return caster->ToGameObject();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WorldObject* AuraScript::GetOwner() const
|
||||
|
||||
@@ -410,6 +410,7 @@ class TC_GAME_API SpellScript : public _SpellScript
|
||||
//
|
||||
// methods useable during all spell handling phases
|
||||
Unit* GetCaster() const;
|
||||
GameObject* GetGObjCaster() const;
|
||||
Unit* GetOriginalCaster() const;
|
||||
SpellInfo const* GetSpellInfo() const;
|
||||
SpellValue const* GetSpellValue() const;
|
||||
@@ -933,6 +934,8 @@ class TC_GAME_API AuraScript : public _SpellScript
|
||||
ObjectGuid GetCasterGUID() const;
|
||||
// returns unit which cast the aura or NULL if not avalible (caster logged out for example)
|
||||
Unit* GetCaster() const;
|
||||
// returns gameobject which cast the aura or NULL if not available
|
||||
GameObject* GetGObjCaster() const;
|
||||
// returns object on which aura was cast, target for non-area auras, area aura source for area auras
|
||||
WorldObject* GetOwner() const;
|
||||
// returns owner if it's unit or unit derived object, NULL otherwise (only for persistent area auras NULL is returned)
|
||||
|
||||
@@ -1865,12 +1865,12 @@ class spell_icc_sprit_alarm : public SpellScriptLoader
|
||||
return;
|
||||
}
|
||||
|
||||
if (GameObject* trap = GetCaster()->FindNearestGameObject(trapId, 5.0f))
|
||||
if (GameObject* trap = GetGObjCaster()->FindNearestGameObject(trapId, 5.0f))
|
||||
trap->SetRespawnTime(trap->GetGOInfo()->GetAutoCloseTime() / IN_MILLISECONDS);
|
||||
|
||||
std::list<Creature*> wards;
|
||||
GetCaster()->GetCreatureListWithEntryInGrid(wards, NPC_DEATHBOUND_WARD, 150.0f);
|
||||
wards.sort(Trinity::ObjectDistanceOrderPred(GetCaster()));
|
||||
GetGObjCaster()->GetCreatureListWithEntryInGrid(wards, NPC_DEATHBOUND_WARD, 150.0f);
|
||||
wards.sort(Trinity::ObjectDistanceOrderPred(GetGObjCaster()));
|
||||
for (std::list<Creature*>::iterator itr = wards.begin(); itr != wards.end(); ++itr)
|
||||
{
|
||||
if ((*itr)->IsAlive() && (*itr)->HasAura(SPELL_STONEFORM))
|
||||
|
||||
@@ -1310,7 +1310,7 @@ class go_ulduar_tower : public GameObjectScript
|
||||
|
||||
InstanceScript* instance;
|
||||
|
||||
void Destroyed(Player* /*player*/, uint32 /*eventId*/) override
|
||||
void Destroyed(WorldObject* /*attacker*/, uint32 /*eventId*/) override
|
||||
{
|
||||
switch (me->GetEntry())
|
||||
{
|
||||
|
||||
@@ -907,15 +907,17 @@ class spell_warl_unstable_affliction : public SpellScriptLoader
|
||||
{
|
||||
if (AuraEffect const* aurEff = GetEffect(EFFECT_1))
|
||||
{
|
||||
Unit* target = dispelInfo->GetDispeller();
|
||||
int32 bp = aurEff->GetAmount();
|
||||
bp = target->SpellDamageBonusTaken(caster, aurEff->GetSpellInfo(), bp, DOT);
|
||||
bp *= 9;
|
||||
if (Unit* target = dispelInfo->GetDispeller()->ToUnit())
|
||||
{
|
||||
int32 bp = aurEff->GetAmount();
|
||||
bp = target->SpellDamageBonusTaken(caster, aurEff->GetSpellInfo(), bp, DOT);
|
||||
bp *= 9;
|
||||
|
||||
// backfire damage and silence
|
||||
CastSpellExtraArgs args(aurEff);
|
||||
args.AddSpellBP0(bp);
|
||||
caster->CastSpell(target, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL, args);
|
||||
// backfire damage and silence
|
||||
CastSpellExtraArgs args(aurEff);
|
||||
args.AddSpellBP0(bp);
|
||||
caster->CastSpell(target, SPELL_WARLOCK_UNSTABLE_AFFLICTION_DISPEL, args);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user