mirror of
https://github.com/mangosfour/server.git
synced 2025-12-17 16:37:00 +00:00
[10465] Implement SPELL_EFFECT_REDIRECT_THREAT
Note: all spells with effect expect additional code for redirection reset. Until code adding redirection work longer that expected. Signed-off-by: VladimirMangos <vladimir@getmangos.com> Patch partly rewrited with move new data into HostileRefManager and added redirection to threatAssist. Also bug fixed with redirection threat to unit not in hostile list yet.
This commit is contained in:
parent
f441216aa0
commit
88cc2d440f
7 changed files with 85 additions and 9 deletions
|
|
@ -21,6 +21,12 @@
|
||||||
#include "Unit.h"
|
#include "Unit.h"
|
||||||
#include "DBCStructure.h"
|
#include "DBCStructure.h"
|
||||||
#include "SpellMgr.h"
|
#include "SpellMgr.h"
|
||||||
|
#include "Map.h"
|
||||||
|
|
||||||
|
HostileRefManager::HostileRefManager( Unit *pOwner ) : iOwner(pOwner), m_redirectionMod(0.0f)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
HostileRefManager::~HostileRefManager()
|
HostileRefManager::~HostileRefManager()
|
||||||
{
|
{
|
||||||
|
|
@ -34,17 +40,34 @@ HostileRefManager::~HostileRefManager()
|
||||||
|
|
||||||
void HostileRefManager::threatAssist(Unit *pVictim, float pThreat, SpellEntry const *pThreatSpell, bool pSingleTarget)
|
void HostileRefManager::threatAssist(Unit *pVictim, float pThreat, SpellEntry const *pThreatSpell, bool pSingleTarget)
|
||||||
{
|
{
|
||||||
HostileReference* ref;
|
float redirectedMod = pVictim->getHostileRefManager().GetThreatRedirectionMod();
|
||||||
|
Unit* redirectedTarget = redirectedMod ? pVictim->getHostileRefManager().GetThreatRedirectionTarget() : NULL;
|
||||||
|
|
||||||
uint32 size = pSingleTarget ? 1 : getSize(); // if pSingleTarget do not devide threat
|
uint32 size = pSingleTarget ? 1 : getSize(); // if pSingleTarget do not devide threat
|
||||||
ref = getFirst();
|
HostileReference* ref = getFirst();
|
||||||
while(ref != NULL)
|
while(ref != NULL)
|
||||||
{
|
{
|
||||||
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, false, (pThreatSpell ? GetSpellSchoolMask(pThreatSpell) : SPELL_SCHOOL_MASK_NORMAL), pThreatSpell);
|
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, false, (pThreatSpell ? GetSpellSchoolMask(pThreatSpell) : SPELL_SCHOOL_MASK_NORMAL), pThreatSpell);
|
||||||
if(pVictim == getOwner())
|
|
||||||
|
if (threat > 0.0f)
|
||||||
|
{
|
||||||
|
if (redirectedTarget && redirectedTarget != ref->getTarget() && redirectedTarget->isAlive())
|
||||||
|
{
|
||||||
|
float redirectedThreat = threat * redirectedMod;
|
||||||
|
threat -= redirectedThreat;
|
||||||
|
|
||||||
|
if(redirectedTarget == getOwner()) // It is faster to modify the threat durectly if possible
|
||||||
|
ref->addThreat(float (threat) / size);
|
||||||
|
else
|
||||||
|
ref->getSource()->addThreat(redirectedTarget, redirectedThreat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pVictim == getOwner())
|
||||||
ref->addThreat(float (threat) / size); // It is faster to modify the threat durectly if possible
|
ref->addThreat(float (threat) / size); // It is faster to modify the threat durectly if possible
|
||||||
else
|
else
|
||||||
ref->getSource()->addThreat(pVictim, float (threat) / size);
|
ref->getSource()->addThreat(pVictim, float (threat) / size);
|
||||||
|
|
||||||
ref = ref->next();
|
ref = ref->next();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -162,4 +185,10 @@ void HostileRefManager::setOnlineOfflineState(Unit *pCreature,bool pIsOnline)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Unit* HostileRefManager::GetThreatRedirectionTarget() const
|
||||||
|
{
|
||||||
|
return !m_redirectionTargetGuid.IsEmpty() ? iOwner->GetMap()->GetUnit(m_redirectionTargetGuid) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//=================================================
|
//=================================================
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
#define _HOSTILEREFMANAGER
|
#define _HOSTILEREFMANAGER
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
#include "ObjectGuid.h"
|
||||||
#include "Utilities/LinkedReference/RefManager.h"
|
#include "Utilities/LinkedReference/RefManager.h"
|
||||||
|
|
||||||
class Unit;
|
class Unit;
|
||||||
|
|
@ -31,10 +32,8 @@ struct SpellEntry;
|
||||||
|
|
||||||
class HostileRefManager : public RefManager<Unit, ThreatManager>
|
class HostileRefManager : public RefManager<Unit, ThreatManager>
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
Unit *iOwner;
|
|
||||||
public:
|
public:
|
||||||
explicit HostileRefManager(Unit *pOwner) { iOwner = pOwner; }
|
explicit HostileRefManager(Unit *pOwner);
|
||||||
~HostileRefManager();
|
~HostileRefManager();
|
||||||
|
|
||||||
Unit* getOwner() { return iOwner; }
|
Unit* getOwner() { return iOwner; }
|
||||||
|
|
@ -64,6 +63,22 @@ 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);
|
||||||
|
|
||||||
|
// redirection threat data
|
||||||
|
void SetThreatRedirection(ObjectGuid guid, uint32 pct)
|
||||||
|
{
|
||||||
|
m_redirectionTargetGuid = guid;
|
||||||
|
m_redirectionMod = pct/100.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float GetThreatRedirectionMod() const { return m_redirectionMod; }
|
||||||
|
Unit* GetThreatRedirectionTarget() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Unit* iOwner; // owner of manager variable, back ref. to it, always exist
|
||||||
|
|
||||||
|
float m_redirectionMod;
|
||||||
|
ObjectGuid m_redirectionTargetGuid;
|
||||||
};
|
};
|
||||||
//=================================================
|
//=================================================
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -304,6 +304,7 @@ class Spell
|
||||||
void EffectCharge(SpellEffectIndex eff_idx);
|
void EffectCharge(SpellEffectIndex eff_idx);
|
||||||
void EffectCharge2(SpellEffectIndex eff_idx);
|
void EffectCharge2(SpellEffectIndex eff_idx);
|
||||||
void EffectProspecting(SpellEffectIndex eff_idx);
|
void EffectProspecting(SpellEffectIndex eff_idx);
|
||||||
|
void EffectRedirectThreat(SpellEffectIndex eff_idx);
|
||||||
void EffectMilling(SpellEffectIndex eff_idx);
|
void EffectMilling(SpellEffectIndex eff_idx);
|
||||||
void EffectRenamePet(SpellEffectIndex eff_idx);
|
void EffectRenamePet(SpellEffectIndex eff_idx);
|
||||||
void EffectSendTaxi(SpellEffectIndex eff_idx);
|
void EffectSendTaxi(SpellEffectIndex eff_idx);
|
||||||
|
|
|
||||||
|
|
@ -190,7 +190,7 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
|
||||||
&Spell::EffectProspecting, //127 SPELL_EFFECT_PROSPECTING Prospecting spell
|
&Spell::EffectProspecting, //127 SPELL_EFFECT_PROSPECTING Prospecting spell
|
||||||
&Spell::EffectApplyAreaAura, //128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
|
&Spell::EffectApplyAreaAura, //128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND
|
||||||
&Spell::EffectApplyAreaAura, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
|
&Spell::EffectApplyAreaAura, //129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY
|
||||||
&Spell::EffectNULL, //130 SPELL_EFFECT_REDIRECT_THREAT
|
&Spell::EffectRedirectThreat, //130 SPELL_EFFECT_REDIRECT_THREAT
|
||||||
&Spell::EffectUnused, //131 SPELL_EFFECT_131 used in some test spells
|
&Spell::EffectUnused, //131 SPELL_EFFECT_131 used in some test spells
|
||||||
&Spell::EffectPlayMusic, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc)
|
&Spell::EffectPlayMusic, //132 SPELL_EFFECT_PLAY_MUSIC sound id in misc value (SoundEntries.dbc)
|
||||||
&Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization
|
&Spell::EffectUnlearnSpecialization, //133 SPELL_EFFECT_UNLEARN_SPECIALIZATION unlearn profession specialization
|
||||||
|
|
@ -8051,6 +8051,12 @@ void Spell::EffectRestoreItemCharges( SpellEffectIndex eff_idx )
|
||||||
item->RestoreCharges();
|
item->RestoreCharges();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Spell::EffectRedirectThreat(SpellEffectIndex eff_idx)
|
||||||
|
{
|
||||||
|
if (unitTarget)
|
||||||
|
m_caster->getHostileRefManager().SetThreatRedirection(unitTarget->GetObjectGuid(), uint32(damage));
|
||||||
|
}
|
||||||
|
|
||||||
void Spell::EffectTeachTaxiNode( SpellEffectIndex eff_idx )
|
void Spell::EffectTeachTaxiNode( SpellEffectIndex eff_idx )
|
||||||
{
|
{
|
||||||
if (unitTarget->GetTypeId() != TYPEID_PLAYER)
|
if (unitTarget->GetTypeId() != TYPEID_PLAYER)
|
||||||
|
|
|
||||||
|
|
@ -392,6 +392,27 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, bool crit, SpellScho
|
||||||
|
|
||||||
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, crit, schoolMask, pThreatSpell);
|
float threat = ThreatCalcHelper::calcThreat(pVictim, iOwner, pThreat, crit, schoolMask, pThreatSpell);
|
||||||
|
|
||||||
|
if (threat > 0.0f)
|
||||||
|
{
|
||||||
|
if (float redirectedMod = pVictim->getHostileRefManager().GetThreatRedirectionMod())
|
||||||
|
{
|
||||||
|
if (Unit* redirectedTarget = pVictim->getHostileRefManager().GetThreatRedirectionTarget())
|
||||||
|
{
|
||||||
|
if (redirectedTarget != getOwner() && redirectedTarget->isAlive())
|
||||||
|
{
|
||||||
|
float redirectedThreat = threat * redirectedMod;
|
||||||
|
threat -= redirectedThreat;
|
||||||
|
addThreatDirectly(redirectedTarget, redirectedThreat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
addThreatDirectly(pVictim, threat);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ThreatManager::addThreatDirectly(Unit* pVictim, float threat)
|
||||||
|
{
|
||||||
HostileReference* ref = iThreatContainer.addThreat(pVictim, threat);
|
HostileReference* ref = iThreatContainer.addThreat(pVictim, threat);
|
||||||
// Ref is online
|
// Ref is online
|
||||||
if (ref)
|
if (ref)
|
||||||
|
|
@ -402,7 +423,7 @@ void ThreatManager::addThreat(Unit* pVictim, float pThreat, bool crit, SpellScho
|
||||||
|
|
||||||
if(!ref) // there was no ref => create a new one
|
if(!ref) // there was no ref => create a new one
|
||||||
{
|
{
|
||||||
// threat has to be 0 here
|
// threat has to be 0 here
|
||||||
HostileReference* hostileReference = new HostileReference(pVictim, this, 0);
|
HostileReference* hostileReference = new HostileReference(pVictim, this, 0);
|
||||||
iThreatContainer.addReference(hostileReference);
|
iThreatContainer.addReference(hostileReference);
|
||||||
hostileReference->addThreat(threat); // now we add the real threat
|
hostileReference->addThreat(threat); // now we add the real threat
|
||||||
|
|
|
||||||
|
|
@ -183,6 +183,10 @@ class MANGOS_DLL_SPEC ThreatManager
|
||||||
|
|
||||||
void addThreat(Unit* pVictim, float threat, bool crit, SpellSchoolMask schoolMask, SpellEntry const *threatSpell);
|
void addThreat(Unit* pVictim, float threat, bool crit, SpellSchoolMask schoolMask, SpellEntry const *threatSpell);
|
||||||
void addThreat(Unit* pVictim, float threat) { addThreat(pVictim,threat,false,SPELL_SCHOOL_MASK_NONE,NULL); }
|
void addThreat(Unit* pVictim, float threat) { addThreat(pVictim,threat,false,SPELL_SCHOOL_MASK_NONE,NULL); }
|
||||||
|
|
||||||
|
// add threat as raw value (ignore redirections and expection all mods applied already to it
|
||||||
|
void addThreatDirectly(Unit* pVictim, float threat);
|
||||||
|
|
||||||
void modifyThreatPercent(Unit *pVictim, int32 pPercent);
|
void modifyThreatPercent(Unit *pVictim, int32 pPercent);
|
||||||
|
|
||||||
float getThreat(Unit *pVictim, bool pAlsoSearchOfflineList = false);
|
float getThreat(Unit *pVictim, bool pAlsoSearchOfflineList = false);
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
#ifndef __REVISION_NR_H__
|
#ifndef __REVISION_NR_H__
|
||||||
#define __REVISION_NR_H__
|
#define __REVISION_NR_H__
|
||||||
#define REVISION_NR "10464"
|
#define REVISION_NR "10465"
|
||||||
#endif // __REVISION_NR_H__
|
#endif // __REVISION_NR_H__
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue