Files
azerothcore-wotlk/src/server/game/Combat/HostileRefMgr.cpp
UltraNix ea24a7b231 fix(Scripts/ZulGurub): Mandokir's Threatening Gaze. (#12095)
* fix(Scripts/ZulGurub: Mandokir's Threatening Gaze.

Boss can melee attack while casting.
Boss charges after the debuff run out.
Guillotine is casted on hit rather than on launch.
Properly coded Threatening Gaze Charge (with dot/hot exceptions)
Whirlwind is removed during charge.
Fixes #11748

* Update

* missing

* Update

* Update.

* Update.

* Update.

* Update.

* Update.
2022-06-26 04:50:50 -03:00

251 lines
6.5 KiB
C++

/*
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by the
* Free Software Foundation; either version 3 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "HostileRefMgr.h"
#include "CreatureAI.h"
#include "SpellInfo.h"
#include "SpellMgr.h"
#include "ThreatMgr.h"
#include "Unit.h"
HostileRefMgr::~HostileRefMgr()
{
deleteReferences();
}
//=================================================
// 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 HostileRefMgr::threatAssist(Unit* victim, float baseThreat, SpellInfo const* threatSpell)
{
if (getSize() == 0)
return;
HostileReference* ref = getFirst();
float threat = ThreatCalcHelper::calcThreat(victim, baseThreat, (threatSpell ? threatSpell->GetSchoolMask() : SPELL_SCHOOL_MASK_NORMAL), threatSpell);
threat /= getSize();
while (ref)
{
Unit* refOwner = ref->GetSource()->GetOwner();
if (ThreatCalcHelper::isValidProcess(victim, refOwner, threatSpell))
{
if (Creature* hatingCreature = refOwner->ToCreature())
{
if (hatingCreature->IsAIEnabled)
{
hatingCreature->AI()->CalculateThreat(victim, threat, threatSpell);
}
}
ref->GetSource()->doAddThreat(victim, threat);
}
ref = ref->next();
}
}
//=================================================
void HostileRefMgr::addTempThreat(float threat, bool apply)
{
HostileReference* ref = getFirst();
while (ref)
{
if (apply)
{
if (ref->getTempThreatModifier() == 0.0f)
ref->addTempThreat(threat);
}
else
ref->resetTempThreat();
ref = ref->next();
}
}
//=================================================
void HostileRefMgr::addThreatPercent(int32 percent)
{
HostileReference* ref = getFirst();
while (ref)
{
ref->addThreatPercent(percent);
ref = ref->next();
}
}
//=================================================
// The online / offline status is given to the method. The calculation has to be done before
void HostileRefMgr::setOnlineOfflineState(bool isOnline)
{
HostileReference* ref = getFirst();
while (ref)
{
ref->setOnlineOfflineState(isOnline);
ref = ref->next();
}
}
//=================================================
// The online / offline status is calculated and set
void HostileRefMgr::updateThreatTables()
{
HostileReference* ref = getFirst();
while (ref)
{
ref->updateOnlineStatus();
ref = ref->next();
}
}
//=================================================
// The references are not needed anymore
// tell the source to remove them from the list and free the mem
void HostileRefMgr::deleteReferences(bool removeFromMap /*= false*/)
{
std::vector<Creature*> creaturesToEvade;
HostileReference* ref = getFirst();
while (ref)
{
HostileReference* nextRef = ref->next();
ref->removeReference();
if (removeFromMap)
{
if (ThreatMgr const* threatMgr = ref->GetSource())
{
if (threatMgr->areThreatListsEmpty())
{
if (Creature* creature = threatMgr->GetOwner()->ToCreature())
{
creaturesToEvade.push_back(creature);
}
}
}
}
delete ref;
ref = nextRef;
}
for (Creature* creature : creaturesToEvade)
{
creature->AI()->EnterEvadeMode();
}
}
//=================================================
// delete one reference, defined by faction
void HostileRefMgr::deleteReferencesForFaction(uint32 faction)
{
HostileReference* ref = getFirst();
while (ref)
{
HostileReference* nextRef = ref->next();
if (ref->GetSource()->GetOwner()->GetFactionTemplateEntry()->faction == faction)
{
ref->removeReference();
delete ref;
}
ref = nextRef;
}
}
//=================================================
// delete one reference, defined by Unit
void HostileRefMgr::deleteReference(Unit* creature)
{
HostileReference* ref = getFirst();
while (ref)
{
HostileReference* nextRef = ref->next();
if (ref->GetSource()->GetOwner() == creature)
{
ref->removeReference();
delete ref;
break;
}
ref = nextRef;
}
}
//=================================================
// delete all references out of specified range
void HostileRefMgr::deleteReferencesOutOfRange(float range)
{
HostileReference* ref = getFirst();
range = range * range;
while (ref)
{
HostileReference* nextRef = ref->next();
Unit* owner = ref->GetSource()->GetOwner();
if (!owner->isActiveObject() && owner->GetExactDist2dSq(GetOwner()) > range)
{
ref->removeReference();
delete ref;
}
ref = nextRef;
}
}
//=================================================
// set state for one reference, defined by Unit
void HostileRefMgr::setOnlineOfflineState(Unit* creature, bool isOnline)
{
HostileReference* ref = getFirst();
while (ref)
{
HostileReference* nextRef = ref->next();
if (ref->GetSource()->GetOwner() == creature)
{
ref->setOnlineOfflineState(isOnline);
break;
}
ref = nextRef;
}
}
//=================================================
void HostileRefMgr::UpdateVisibility(bool checkThreat)
{
HostileReference* ref = getFirst();
while (ref)
{
HostileReference* nextRef = ref->next();
if ((!checkThreat || ref->GetSource()->getThreatList().size() <= 1))
{
nextRef = ref->next();
ref->removeReference();
delete ref;
}
ref = nextRef;
}
}