Core/Spells: Fix spelleffect sanctuary
- No longer removes every attacker, but updates the visibility - Using that effect won't remove attackers that can still see through the stealth of the caster based on distance - Ignores spells that were casted before or at the same time of that effect - Trigger other needed spells when casting Shadowmeld --HG-- branch : trunk
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
DELETE FROM `spell_linked_spell` WHERE `spell_trigger` IN (58984);
|
||||||
|
INSERT INTO `spell_linked_spell` (`spell_trigger`,`spell_effect`,`type`,`comment`) VALUES
|
||||||
|
(58984, 59646, 0, 'Shadowmeld: Sanctuary'),
|
||||||
|
(58984, 62196, 0, 'Shadowmeld: Force deselect');
|
||||||
@@ -185,3 +185,18 @@ void HostileRefManager::setOnlineOfflineState(Unit *pCreature, bool bIsOnline)
|
|||||||
|
|
||||||
//=================================================
|
//=================================================
|
||||||
|
|
||||||
|
void HostileRefManager::UpdateVisibility()
|
||||||
|
{
|
||||||
|
HostileReference* ref = getFirst();
|
||||||
|
while (ref)
|
||||||
|
{
|
||||||
|
HostileReference* nextRef = ref->next();
|
||||||
|
if (!ref->getSource()->getOwner()->canSeeOrDetect(getOwner()))
|
||||||
|
{
|
||||||
|
HostileReference* nextRef = ref->next();
|
||||||
|
ref->removeReference();
|
||||||
|
delete ref;
|
||||||
|
}
|
||||||
|
ref = nextRef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -66,6 +66,8 @@ class HostileRefManager : public RefManager<Unit, ThreatManager>
|
|||||||
|
|
||||||
// delete one reference, defined by Unit
|
// delete one reference, defined by Unit
|
||||||
void deleteReference(Unit *pCreature);
|
void deleteReference(Unit *pCreature);
|
||||||
|
|
||||||
|
void UpdateVisibility();
|
||||||
};
|
};
|
||||||
//=================================================
|
//=================================================
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ Unit::Unit(): WorldObject(),
|
|||||||
m_movedPlayer(NULL), IsAIEnabled(false), NeedChangeAI(false),
|
m_movedPlayer(NULL), IsAIEnabled(false), NeedChangeAI(false),
|
||||||
m_ControlledByPlayer(false), i_AI(NULL), i_disabledAI(NULL), m_procDeep(0),
|
m_ControlledByPlayer(false), i_AI(NULL), i_disabledAI(NULL), m_procDeep(0),
|
||||||
m_removedAurasCount(0), i_motionMaster(this), m_ThreatManager(this), m_vehicle(NULL),
|
m_removedAurasCount(0), i_motionMaster(this), m_ThreatManager(this), m_vehicle(NULL),
|
||||||
m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefManager(this)
|
m_vehicleKit(NULL), m_unitTypeMask(UNIT_MASK_NONE), m_HostileRefManager(this), m_lastSanctuaryTime(0)
|
||||||
{
|
{
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(default:4355)
|
#pragma warning(default:4355)
|
||||||
|
|||||||
@@ -1774,6 +1774,7 @@ class Unit : public WorldObject
|
|||||||
void UpdateObjectVisibility(bool forced = true);
|
void UpdateObjectVisibility(bool forced = true);
|
||||||
|
|
||||||
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
|
SpellImmuneList m_spellImmune[MAX_SPELL_IMMUNITY];
|
||||||
|
uint32 m_lastSanctuaryTime;
|
||||||
|
|
||||||
// Threat related methods
|
// Threat related methods
|
||||||
bool CanHaveThreatList() const;
|
bool CanHaveThreatList() const;
|
||||||
|
|||||||
@@ -1138,6 +1138,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo *target)
|
|||||||
if (unit->isAlive() != target->alive)
|
if (unit->isAlive() != target->alive)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
if (getState() == SPELL_STATE_DELAYED && !IsPositiveSpell(m_spellInfo->Id) && (getMSTime() - target->timeDelay) <= unit->m_lastSanctuaryTime)
|
||||||
|
return; // No missinfo in that case
|
||||||
|
|
||||||
// Get original caster (if exist) and calculate damage/healing from him data
|
// Get original caster (if exist) and calculate damage/healing from him data
|
||||||
Unit *caster = m_originalCaster ? m_originalCaster : m_caster;
|
Unit *caster = m_originalCaster ? m_originalCaster : m_caster;
|
||||||
|
|
||||||
@@ -3414,7 +3417,10 @@ uint64 Spell::handle_delayed(uint64 t_offset)
|
|||||||
if (ihit->processed == false)
|
if (ihit->processed == false)
|
||||||
{
|
{
|
||||||
if (single_missile || ihit->timeDelay <= t_offset)
|
if (single_missile || ihit->timeDelay <= t_offset)
|
||||||
|
{
|
||||||
|
ihit->timeDelay = t_offset;
|
||||||
DoAllEffectOnTarget(&(*ihit));
|
DoAllEffectOnTarget(&(*ihit));
|
||||||
|
}
|
||||||
else if (next_time == 0 || ihit->timeDelay < next_time)
|
else if (next_time == 0 || ihit->timeDelay < next_time)
|
||||||
next_time = ihit->timeDelay;
|
next_time = ihit->timeDelay;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5326,27 +5326,9 @@ void Spell::EffectSanctuary(SpellEffIndex /*effIndex*/)
|
|||||||
if (!unitTarget)
|
if (!unitTarget)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
std::list<Unit*> targets;
|
unitTarget->getHostileRefManager().UpdateVisibility();
|
||||||
Trinity::AnyUnfriendlyUnitInObjectRangeCheck u_check(unitTarget, unitTarget, m_caster->GetMap()->GetVisibilityRange());
|
unitTarget->m_lastSanctuaryTime = getMSTime();
|
||||||
Trinity::UnitListSearcher<Trinity::AnyUnfriendlyUnitInObjectRangeCheck> searcher(unitTarget, targets, u_check);
|
|
||||||
unitTarget->VisitNearbyObject(m_caster->GetMap()->GetVisibilityRange(), searcher);
|
|
||||||
for (std::list<Unit*>::iterator iter = targets.begin(); iter != targets.end(); ++iter)
|
|
||||||
{
|
|
||||||
if (!(*iter)->hasUnitState(UNIT_STAT_CASTING))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (uint32 i = CURRENT_FIRST_NON_MELEE_SPELL; i < CURRENT_MAX_SPELL; i++)
|
|
||||||
{
|
|
||||||
if ((*iter)->GetCurrentSpell(i)
|
|
||||||
&& (*iter)->GetCurrentSpell(i)->m_targets.getUnitTargetGUID() == unitTarget->GetGUID())
|
|
||||||
{
|
|
||||||
(*iter)->InterruptSpell(CurrentSpellTypes(i), false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unitTarget->CombatStop();
|
|
||||||
unitTarget->getHostileRefManager().deleteReferences(); // stop all fighting
|
|
||||||
// Vanish allows to remove all threat and cast regular stealth so other spells can be used
|
// Vanish allows to remove all threat and cast regular stealth so other spells can be used
|
||||||
if (m_caster->GetTypeId() == TYPEID_PLAYER
|
if (m_caster->GetTypeId() == TYPEID_PLAYER
|
||||||
&& m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE
|
&& m_spellInfo->SpellFamilyName == SPELLFAMILY_ROGUE
|
||||||
|
|||||||
Reference in New Issue
Block a user