Core/Spells: rework part 5: GameObject casting

Closes #21330
Closes #18885
Ref #18752

(cherry picked from commit 45c5e1b9d63796d168339a44f63418f220cf2403)
This commit is contained in:
ariel-
2021-08-28 15:59:11 +02:00
committed by Shauren
parent 65dca120d3
commit 962f6d7988
46 changed files with 2775 additions and 2419 deletions
+11 -3
View File
@@ -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
+4 -2
View File
@@ -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)
{
+2 -2
View File
@@ -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)
+1 -1
View File
@@ -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;
+10 -9
View File
@@ -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;
+8 -7
View File
@@ -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(); }
+3 -1
View File
@@ -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)
+2 -2
View File
@@ -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
+75 -3
View File
@@ -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
+7 -46
View File
@@ -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)
+3 -8
View File
@@ -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);
+1 -1
View File
@@ -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)
+1 -1
View File
@@ -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
+24 -71
View File
@@ -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&);
+11 -15
View File
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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>
+15 -9
View File
@@ -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),
File diff suppressed because it is too large Load Diff
+43 -37
View File
@@ -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
+1 -1
View File
@@ -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
+108 -83
View File
@@ -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)))
{
+15 -15
View File
@@ -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; }
+17 -3
View File
@@ -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
+3
View File
@@ -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())
{
+10 -8
View File
@@ -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);
}
}
}
}