Core/Misc: fix interaction of spells like Shadowmeld with Threat reducing effects

- SPELL_AURA_MOD_TOTAL_THREAT should be temporary and not added/subtracted from total, only computed
- Cleanup of reference related code
- Kill getLast() and reverse iterator obsevers, LinkedList iterator can't be used as a standard reverse_iterator (ie with operator++). They weren't used anyways

(cherry picked from commit 3b6fd226be)

# Conflicts:
#	src/server/game/Combat/ThreatManager.cpp
#	src/server/game/Loot/LootMgr.h
This commit is contained in:
ariel-
2016-10-06 23:14:51 -03:00
committed by joschiwald
parent ab916fd1b3
commit ec3dc0a431
12 changed files with 117 additions and 124 deletions

View File

@@ -28,8 +28,8 @@ HostileRefManager::~HostileRefManager()
}
//=================================================
// send threat to all my hateres for the victim
// The victim is hated than by them as well
// send threat to all my haters for the victim
// The victim is then hated by them as well
// use for buffs and healing threat functionality
void HostileRefManager::threatAssist(Unit* victim, float baseThreat, SpellInfo const* threatSpell)
@@ -37,9 +37,10 @@ void HostileRefManager::threatAssist(Unit* victim, float baseThreat, SpellInfo c
if (getSize() == 0)
return;
HostileReference* ref = getFirst();
float threat = ThreatCalcHelper::calcThreat(victim, iOwner, baseThreat, (threatSpell ? threatSpell->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL), threatSpell);
threat /= getSize();
HostileReference* ref = getFirst();
while (ref)
{
if (ThreatCalcHelper::isValidProcess(victim, ref->GetSource()->GetOwner(), threatSpell))
@@ -54,7 +55,6 @@ void HostileRefManager::threatAssist(Unit* victim, float baseThreat, SpellInfo c
void HostileRefManager::addTempThreat(float threat, bool apply)
{
HostileReference* ref = getFirst();
while (ref)
{
if (apply)

View File

@@ -31,18 +31,16 @@ class SpellInfo;
class TC_GAME_API HostileRefManager : public RefManager<Unit, ThreatManager>
{
private:
Unit* iOwner;
public:
explicit HostileRefManager(Unit* owner) { iOwner = owner; }
explicit HostileRefManager(Unit* owner) : iOwner(owner) { }
~HostileRefManager();
Unit* GetOwner() { return iOwner; }
Unit* GetOwner() const { return iOwner; }
// send threat to all my hateres for the victim
// The victim is hated than by them as well
// use for buffs and healing threat functionality
void threatAssist(Unit* victim, float baseThreat, SpellInfo const* threatSpell = NULL);
void threatAssist(Unit* victim, float baseThreat, SpellInfo const* threatSpell = nullptr);
void addTempThreat(float threat, bool apply);
@@ -68,6 +66,9 @@ class TC_GAME_API HostileRefManager : public RefManager<Unit, ThreatManager>
void deleteReference(Unit* creature);
void UpdateVisibility();
private:
Unit* iOwner;
};
//=================================================
#endif

View File

@@ -31,7 +31,7 @@
//==============================================================
// The hatingUnit is not used yet
float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float threat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell)
float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float threat, SpellSchoolMask schoolMask, SpellInfo const* threatSpell /*= nullptr*/)
{
if (threatSpell)
{
@@ -40,7 +40,7 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float
threat *= threatEntry->pctMod;
// Energize is not affected by Mods
for (SpellEffectInfo const* effect : threatSpell->GetEffectsForDifficulty(hatedUnit->GetMap()->GetDifficultyID()))
for (SpellEffectInfo const* effect : threatSpell->GetEffectsForDifficulty(hatedUnit->GetMap()->GetDifficultyID()))
if (effect && (effect->Effect == SPELL_EFFECT_ENERGIZE || effect->ApplyAuraName == SPELL_AURA_PERIODIC_ENERGIZE))
return threat;
@@ -51,7 +51,7 @@ float ThreatCalcHelper::calcThreat(Unit* hatedUnit, Unit* /*hatingUnit*/, float
return hatedUnit->ApplyTotalThreatModifier(threat, schoolMask);
}
bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell)
bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell /*= nullptr*/)
{
//function deals with adding threat and adding players and pets into ThreatList
//mobs, NPCs, guards have ThreatList and HateOfflineList
@@ -135,18 +135,20 @@ void HostileReference::fireStatusChanged(ThreatRefStatusChangeEvent& threatRefSt
void HostileReference::addThreat(float modThreat)
{
if (!modThreat)
return;
iThreat += modThreat;
// the threat is changed. Source and target unit have to be available
// if the link was cut before relink it again
if (!isOnline())
updateOnlineStatus();
if (modThreat != 0.0f)
{
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, modThreat);
fireStatusChanged(event);
}
if (isValid() && modThreat >= 0.0f)
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, modThreat);
fireStatusChanged(event);
if (isValid() && modThreat > 0.0f)
{
Unit* victimOwner = getTarget()->GetCharmerOrOwner();
if (victimOwner && victimOwner->IsAlive())
@@ -156,9 +158,7 @@ void HostileReference::addThreat(float modThreat)
void HostileReference::addThreatPercent(int32 percent)
{
float tmpThreat = iThreat;
AddPct(tmpThreat, percent);
addThreat(tmpThreat - iThreat);
addThreat(CalculatePct(iThreat, percent));
}
//============================================================
@@ -194,6 +194,7 @@ void HostileReference::updateOnlineStatus()
else
accessible = true;
}
setAccessibleState(accessible);
setOnlineOfflineState(online);
}
@@ -222,7 +223,7 @@ void HostileReference::setAccessibleState(bool isAccessible)
{
iAccessible = isAccessible;
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_ASSECCIBLE_STATUS, this);
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_ACCESSIBLE_STATUS, this);
fireStatusChanged(event);
}
}

View File

@@ -41,8 +41,8 @@ class SpellInfo;
struct TC_GAME_API ThreatCalcHelper
{
static float calcThreat(Unit* hatedUnit, Unit* hatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = NULL);
static bool isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell = NULL);
static float calcThreat(Unit* hatedUnit, Unit* hatingUnit, float threat, SpellSchoolMask schoolMask = SPELL_SCHOOL_MASK_NORMAL, SpellInfo const* threatSpell = nullptr);
static bool isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellInfo const* threatSpell = nullptr);
};
//==============================================================
@@ -54,11 +54,11 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
//=================================================
void addThreat(float modThreat);
void setThreat(float threat) { addThreat(threat - getThreat()); }
void setThreat(float threat) { addThreat(threat - iThreat); }
void addThreatPercent(int32 percent);
float getThreat() const { return iThreat; }
float getThreat() const { return iThreat + iTempThreatModifier; }
bool isOnline() const { return iOnline; }
@@ -66,27 +66,27 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
// in this case online = true, but accessible = false
bool isAccessible() const { return iAccessible; }
// used for temporary setting a threat and reducting it later again.
// used for temporary setting a threat and reducing it later again.
// the threat modification is stored
void setTempThreat(float threat)
{
addTempThreat(threat - getThreat());
addTempThreat(threat - iTempThreatModifier);
}
void addTempThreat(float threat)
{
iTempThreatModifier = threat;
if (iTempThreatModifier != 0.0f)
addThreat(iTempThreatModifier);
if (!threat)
return;
iTempThreatModifier += threat;
ThreatRefStatusChangeEvent event(UEV_THREAT_REF_THREAT_CHANGE, this, threat);
fireStatusChanged(event);
}
void resetTempThreat()
{
if (iTempThreatModifier != 0.0f)
{
addThreat(-iTempThreatModifier);
iTempThreatModifier = 0.0f;
}
addTempThreat(-iTempThreatModifier);
}
float getTempThreatModifier() { return iTempThreatModifier; }
@@ -100,7 +100,7 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
void setAccessibleState(bool isAccessible);
//=================================================
bool operator == (const HostileReference& hostileRef) const { return hostileRef.getUnitGuid() == getUnitGuid(); }
bool operator==(HostileReference const& hostileRef) const { return hostileRef.getUnitGuid() == getUnitGuid(); }
//=================================================
@@ -113,7 +113,7 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
//=================================================
HostileReference* next() { return ((HostileReference*) Reference<Unit, ThreatManager>::next()); }
HostileReference* next() { return static_cast<HostileReference*>(Reference<Unit, ThreatManager>::next()); }
//=================================================
@@ -125,14 +125,17 @@ class TC_GAME_API HostileReference : public Reference<Unit, ThreatManager>
// Tell our refFrom (source) object, that the link is cut (Target destroyed)
void sourceObjectDestroyLink() override;
private:
// Inform the source, that the status of that reference was changed
void fireStatusChanged(ThreatRefStatusChangeEvent& threatRefStatusChangeEvent);
Unit* GetSourceUnit();
private:
float iThreat;
float iTempThreatModifier; // used for taunt
float iTempThreatModifier; // used for SPELL_AURA_MOD_TOTAL_THREAT
ObjectGuid iUnitGuid;
bool iOnline;
bool iAccessible;

View File

@@ -40,7 +40,7 @@ enum UNIT_EVENT_TYPE
UEV_THREAT_REF_REMOVE_FROM_LIST = 1<<2,
// Player/Pet entered/left water or some other place where it is/was not accessible for the creature
UEV_THREAT_REF_ASSECCIBLE_STATUS = 1<<3,
UEV_THREAT_REF_ACCESSIBLE_STATUS = 1<<3,
// Threat list is going to be sorted (if dirty flag is set)
UEV_THREAT_SORT_LIST = 1<<4,
@@ -58,7 +58,7 @@ enum UNIT_EVENT_TYPE
//UEV_UNIT_HEALTH_CHANGE = 1<<8,
};
#define UEV_THREAT_REF_EVENT_MASK (UEV_THREAT_REF_ONLINE_STATUS | UEV_THREAT_REF_THREAT_CHANGE | UEV_THREAT_REF_REMOVE_FROM_LIST | UEV_THREAT_REF_ASSECCIBLE_STATUS)
#define UEV_THREAT_REF_EVENT_MASK (UEV_THREAT_REF_ONLINE_STATUS | UEV_THREAT_REF_THREAT_CHANGE | UEV_THREAT_REF_REMOVE_FROM_LIST | UEV_THREAT_REF_ACCESSIBLE_STATUS)
#define UEV_THREAT_MANAGER_EVENT_MASK (UEV_THREAT_SORT_LIST | UEV_THREAT_SET_NEXT_TARGET | UEV_THREAT_VICTIM_CHANGED)
#define UEV_ALL_EVENT_MASK (0xffffffff)
@@ -69,14 +69,16 @@ enum UNIT_EVENT_TYPE
class UnitBaseEvent
{
private:
uint32 iType;
public:
UnitBaseEvent(uint32 pType) { iType = pType; }
explicit UnitBaseEvent(uint32 pType) { iType = pType; }
uint32 getType() const { return iType; }
bool matchesTypeMask(uint32 pMask) const { return (iType & pMask) != 0; }
void setType(uint32 pType) { iType = pType; }
private:
uint32 iType;
protected:
~UnitBaseEvent() { }
};
//==============================================================
@@ -92,14 +94,15 @@ class TC_GAME_API ThreatRefStatusChangeEvent : public UnitBaseEvent
bool iBValue;
};
ThreatManager* iThreatManager;
public:
ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iThreatManager(NULL) { iHostileReference = NULL; }
explicit ThreatRefStatusChangeEvent(uint32 pType) : UnitBaseEvent(pType), iHostileReference(nullptr), iThreatManager(nullptr) { }
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iThreatManager(NULL) { iHostileReference = pHostileReference; }
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference) : UnitBaseEvent(pType), iHostileReference(pHostileReference), iThreatManager(nullptr) { }
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iThreatManager(NULL) { iHostileReference = pHostileReference; iFValue = pValue; }
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, float pValue) : UnitBaseEvent(pType), iHostileReference(pHostileReference), iFValue(pValue), iThreatManager(nullptr) { }
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iThreatManager(NULL) { iHostileReference = pHostileReference; iBValue = pValue; }
ThreatRefStatusChangeEvent(uint32 pType, HostileReference* pHostileReference, bool pValue) : UnitBaseEvent(pType), iHostileReference(pHostileReference), iBValue(pValue), iThreatManager(nullptr) { }
int32 getIValue() const { return iIValue; }
@@ -116,20 +119,4 @@ class TC_GAME_API ThreatRefStatusChangeEvent : public UnitBaseEvent
ThreatManager* getThreatManager() const { return iThreatManager; }
};
//==============================================================
class ThreatManagerEvent : public ThreatRefStatusChangeEvent
{
private:
ThreatContainer* iThreatContainer;
public:
ThreatManagerEvent(uint32 pType) : ThreatRefStatusChangeEvent(pType), iThreatContainer(NULL) { }
ThreatManagerEvent(uint32 pType, HostileReference* pHostileReference) : ThreatRefStatusChangeEvent(pType, pHostileReference), iThreatContainer(NULL) { }
void setThreatContainer(ThreatContainer* pThreatContainer) { iThreatContainer = pThreatContainer; }
ThreatContainer* getThreatContainer() const { return iThreatContainer; }
};
//==============================================================
#endif

View File

@@ -35,7 +35,5 @@ class GridRefManager : public RefManager<GridRefManager<OBJECT>, OBJECT>
iterator begin() { return iterator(getFirst()); }
iterator end() { return iterator(NULL); }
iterator rbegin() { return iterator(getLast()); }
iterator rend() { return iterator(NULL); }
};
#endif

View File

@@ -199,12 +199,9 @@ public:
typedef LinkedListHead::Iterator<LootValidatorRef> iterator;
LootValidatorRef* getFirst() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getFirst(); }
LootValidatorRef* getLast() { return (LootValidatorRef*)RefManager<Loot, LootValidatorRef>::getLast(); }
iterator begin() { return iterator(getFirst()); }
iterator end() { return iterator(NULL); }
iterator rbegin() { return iterator(getLast()); }
iterator rend() { return iterator(NULL); }
iterator end() { return iterator(nullptr); }
};
//=====================================================

View File

@@ -131,8 +131,8 @@ class TC_GAME_API LootTemplate
LootGroups Groups; // groups have own (optimised) processing, grouped entries go there
// Objects of this class must never be copied, we are storing pointers in container
LootTemplate(LootTemplate const&);
LootTemplate& operator=(LootTemplate const&);
LootTemplate(LootTemplate const&) = delete;
LootTemplate& operator=(LootTemplate const&) = delete;
};
//=====================================================

View File

@@ -26,20 +26,17 @@ class MapReference;
class MapRefManager : public RefManager<Map, Player>
{
public:
typedef LinkedListHead::Iterator< MapReference > iterator;
typedef LinkedListHead::Iterator< MapReference const > const_iterator;
typedef LinkedListHead::Iterator<MapReference> iterator;
typedef LinkedListHead::Iterator<MapReference const> const_iterator;
MapReference* getFirst() { return (MapReference*)RefManager<Map, Player>::getFirst(); }
MapReference* getFirst() { return (MapReference*)RefManager<Map, Player>::getFirst(); }
MapReference const* getFirst() const { return (MapReference const*)RefManager<Map, Player>::getFirst(); }
MapReference* getLast() { return (MapReference*)RefManager<Map, Player>::getLast(); }
MapReference const* getLast() const { return (MapReference const*)RefManager<Map, Player>::getLast(); }
iterator begin() { return iterator(getFirst()); }
iterator end() { return iterator(NULL); }
iterator rbegin() { return iterator(getLast()); }
iterator rend() { return iterator(NULL); }
iterator end() { return iterator(nullptr); }
const_iterator begin() const { return const_iterator(getFirst()); }
const_iterator end() const { return const_iterator(NULL); }
const_iterator end() const { return const_iterator(nullptr); }
};
#endif

View File

@@ -32,18 +32,18 @@ class LinkedListElement
LinkedListElement* iNext;
LinkedListElement* iPrev;
public:
LinkedListElement() : iNext(NULL), iPrev(NULL) { }
virtual ~LinkedListElement() { delink(); }
LinkedListElement() : iNext(nullptr), iPrev(nullptr) { }
bool hasNext() const { return(iNext && iNext->iNext != NULL); }
bool hasPrev() const { return(iPrev && iPrev->iPrev != NULL); }
bool isInList() const { return(iNext != NULL && iPrev != NULL); }
bool hasNext() const { return (iNext && iNext->iNext != nullptr); }
bool hasPrev() const { return (iPrev && iPrev->iPrev != nullptr); }
bool isInList() const { return (iNext != nullptr && iPrev != nullptr); }
LinkedListElement * next() { return hasNext() ? iNext : NULL; }
LinkedListElement const* next() const { return hasNext() ? iNext : NULL; }
LinkedListElement * prev() { return hasPrev() ? iPrev : NULL; }
LinkedListElement const* prev() const { return hasPrev() ? iPrev : NULL; }
LinkedListElement * next() { return hasNext() ? iNext : nullptr; }
LinkedListElement const* next() const { return hasNext() ? iNext : nullptr; }
LinkedListElement * prev() { return hasPrev() ? iPrev : nullptr; }
LinkedListElement const* prev() const { return hasPrev() ? iPrev : nullptr; }
LinkedListElement * nocheck_next() { return iNext; }
LinkedListElement const* nocheck_next() const { return iNext; }
@@ -52,10 +52,13 @@ class LinkedListElement
void delink()
{
if (isInList())
{
iNext->iPrev = iPrev; iPrev->iNext = iNext; iNext = NULL; iPrev = NULL;
}
if (!isInList())
return;
iNext->iPrev = iPrev;
iPrev->iNext = iNext;
iNext = nullptr;
iPrev = nullptr;
}
void insertBefore(LinkedListElement* pElem)
@@ -75,8 +78,14 @@ class LinkedListElement
}
private:
LinkedListElement(LinkedListElement const&);
LinkedListElement& operator=(LinkedListElement const&);
LinkedListElement(LinkedListElement const&) = delete;
LinkedListElement& operator=(LinkedListElement const&) = delete;
protected:
~LinkedListElement()
{
delink();
}
};
//============================================
@@ -97,15 +106,13 @@ class LinkedListHead
iLast.iPrev = &iFirst;
}
virtual ~LinkedListHead() { }
bool isEmpty() const { return(!iFirst.iNext->isInList()); }
LinkedListElement * getFirst() { return(isEmpty() ? NULL : iFirst.iNext); }
LinkedListElement const* getFirst() const { return(isEmpty() ? NULL : iFirst.iNext); }
LinkedListElement * getFirst() { return (isEmpty() ? nullptr : iFirst.iNext); }
LinkedListElement const* getFirst() const { return (isEmpty() ? nullptr : iFirst.iNext); }
LinkedListElement * getLast() { return(isEmpty() ? NULL : iLast.iPrev); }
LinkedListElement const* getLast() const { return(isEmpty() ? NULL : iLast.iPrev); }
LinkedListElement * getLast() { return(isEmpty() ? nullptr : iLast.iPrev); }
LinkedListElement const* getLast() const { return(isEmpty() ? nullptr : iLast.iPrev); }
void insertFirst(LinkedListElement* pElem)
{
@@ -248,8 +255,11 @@ class LinkedListHead
typedef Iterator<LinkedListElement> iterator;
private:
LinkedListHead(LinkedListHead const&);
LinkedListHead& operator=(LinkedListHead const&);
LinkedListHead(LinkedListHead const&) = delete;
LinkedListHead& operator=(LinkedListHead const&) = delete;
protected:
~LinkedListHead() { }
};
//============================================

View File

@@ -23,31 +23,29 @@
#include "Dynamic/LinkedList.h"
#include "Dynamic/LinkedReference/Reference.h"
template <class TO, class FROM> class RefManager : public LinkedListHead
template <class TO, class FROM>
class RefManager : public LinkedListHead
{
public:
typedef LinkedListHead::Iterator< Reference<TO, FROM> > iterator;
typedef LinkedListHead::Iterator<Reference<TO, FROM>> iterator;
RefManager() { }
virtual ~RefManager() { clearReferences(); }
Reference<TO, FROM>* getFirst() { return ((Reference<TO, FROM>*) LinkedListHead::getFirst()); }
Reference<TO, FROM> const* getFirst() const { return ((Reference<TO, FROM> const*) LinkedListHead::getFirst()); }
Reference<TO, FROM>* getLast() { return ((Reference<TO, FROM>*) LinkedListHead::getLast()); }
Reference<TO, FROM> const* getLast() const { return ((Reference<TO, FROM> const*) LinkedListHead::getLast()); }
Reference<TO, FROM>* getFirst() { return static_cast<Reference<TO, FROM>*>(LinkedListHead::getFirst()); }
Reference<TO, FROM> const* getFirst() const { return static_cast<Reference<TO, FROM> const*>(LinkedListHead::getFirst()); }
iterator begin() { return iterator(getFirst()); }
iterator end() { return iterator(NULL); }
iterator rbegin() { return iterator(getLast()); }
iterator rend() { return iterator(NULL); }
iterator end() { return iterator(nullptr); }
virtual ~RefManager()
{
clearReferences();
}
void clearReferences()
{
LinkedListElement* ref;
while ((ref = getFirst()) != NULL)
{
((Reference<TO, FROM>*) ref)->invalidate();
ref->delink(); // the delink might be already done by invalidate(), but doing it here again does not hurt and insures an empty list
}
while (Reference<TO, FROM>* ref = getFirst())
ref->invalidate();
}
};

View File

@@ -29,6 +29,7 @@ template <class TO, class FROM> class Reference : public LinkedListElement
private:
TO* iRefTo;
FROM* iRefFrom;
protected:
// Tell our refTo (target) object that we have a link
virtual void targetObjectBuildLink() = 0;
@@ -90,14 +91,14 @@ template <class TO, class FROM> class Reference : public LinkedListElement
Reference<TO, FROM> * nocheck_prev() { return((Reference<TO, FROM> *) LinkedListElement::nocheck_prev()); }
Reference<TO, FROM> const* nocheck_prev() const { return((Reference<TO, FROM> const*) LinkedListElement::nocheck_prev()); }
TO* operator ->() const { return iRefTo; }
TO* operator->() const { return iRefTo; }
TO* getTarget() const { return iRefTo; }
FROM* GetSource() const { return iRefFrom; }
private:
Reference(Reference const&);
Reference& operator=(Reference const&);
Reference(Reference const&) = delete;
Reference& operator=(Reference const&) = delete;
};
//=====================================================