mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-30 17:13:47 +00:00
Merge branch 'azerothcore:master' into Playerbot
This commit is contained in:
@@ -386,6 +386,8 @@ public:
|
||||
|
||||
void ModifyThreatPercentTemp(Unit* victim, int32 percent, Milliseconds duration);
|
||||
|
||||
void ResetFaction() { SetFaction(GetCreatureTemplate()->faction); }
|
||||
|
||||
protected:
|
||||
bool CreateFromProto(ObjectGuid::LowType guidlow, uint32 Entry, uint32 vehId, const CreatureData* data = nullptr);
|
||||
bool InitEntry(uint32 entry, const CreatureData* data = nullptr);
|
||||
|
||||
@@ -701,8 +701,8 @@ void GameObject::Update(uint32 diff)
|
||||
// search unfriendly creature
|
||||
if (owner && goInfo->trap.autoCloseTime != -1) // hunter trap
|
||||
{
|
||||
Acore::AnyUnfriendlyNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
|
||||
Acore::UnitSearcher<Acore::AnyUnfriendlyNoTotemUnitInObjectRangeCheck> searcher(this, target, checker);
|
||||
Acore::NearestAttackableNoTotemUnitInObjectRangeCheck checker(this, owner, radius);
|
||||
Acore::UnitSearcher<Acore::NearestAttackableNoTotemUnitInObjectRangeCheck> searcher(this, target, checker);
|
||||
Cell::VisitAllObjects(this, searcher, radius);
|
||||
}
|
||||
else // environmental trap
|
||||
|
||||
@@ -2949,7 +2949,15 @@ template <class T> T Player::ApplySpellMod(uint32 spellId, SpellModOp op, T& bas
|
||||
return;
|
||||
}
|
||||
|
||||
totalflat += mod->value;
|
||||
int32 flatValue = mod->value;
|
||||
|
||||
// SPELL_MOD_THREAT - divide by 100 (in packets we send threat * 100)
|
||||
if (mod->op == SPELLMOD_THREAT)
|
||||
{
|
||||
flatValue /= 100;
|
||||
}
|
||||
|
||||
totalflat += flatValue;
|
||||
}
|
||||
else if (mod->type == SPELLMOD_PCT)
|
||||
{
|
||||
|
||||
@@ -12422,7 +12422,7 @@ bool Unit::IsImmunedToSpell(SpellInfo const* spellInfo)
|
||||
{
|
||||
SpellInfo const* immuneSpellInfo = sSpellMgr->GetSpellInfo(itr->spellId);
|
||||
if (((itr->type & spellInfo->GetSchoolMask()) == spellInfo->GetSchoolMask())
|
||||
&& !(immuneSpellInfo && immuneSpellInfo->IsPositive()) && !spellInfo->IsPositive()
|
||||
&& (!immuneSpellInfo || immuneSpellInfo->IsPositive()) && !spellInfo->IsPositive()
|
||||
&& !spellInfo->CanPierceImmuneAura(immuneSpellInfo))
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -898,6 +898,47 @@ namespace Acore
|
||||
float i_range;
|
||||
};
|
||||
|
||||
class NearestAttackableNoTotemUnitInObjectRangeCheck
|
||||
{
|
||||
public:
|
||||
NearestAttackableNoTotemUnitInObjectRangeCheck(WorldObject const* obj, Unit const* owner, float range) : i_obj(obj), i_owner(owner), i_range(range) {}
|
||||
|
||||
bool operator()(Unit* u)
|
||||
{
|
||||
if (!u->IsAlive())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (u->GetCreatureType() == CREATURE_TYPE_NON_COMBAT_PET)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (u->GetTypeId() == TYPEID_UNIT && u->ToCreature()->IsTotem())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!u->isTargetableForAttack(false, i_owner))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!i_obj->IsWithinDistInMap(u, i_range) || !i_owner->IsValidAttackTarget(u) || !i_obj->IsWithinLOSInMap(u))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
WorldObject const* i_obj;
|
||||
Unit const* i_owner;
|
||||
float i_range;
|
||||
};
|
||||
|
||||
class AnyUnfriendlyAttackableVisibleUnitInObjectRangeCheck
|
||||
{
|
||||
public:
|
||||
@@ -1037,8 +1078,19 @@ namespace Acore
|
||||
bool operator()(Unit* u)
|
||||
{
|
||||
// Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems
|
||||
if (u->GetTypeId() == TYPEID_UNIT && ((Creature*)u)->IsTotem())
|
||||
return false;
|
||||
if (Creature* creature = u->ToCreature())
|
||||
{
|
||||
if (creature->IsTotem())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (creature->IsAvoidingAOE())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (i_funit->_IsValidAttackTarget(u, _spellInfo, i_obj->GetTypeId() == TYPEID_DYNAMICOBJECT ? i_obj : nullptr) && i_obj->IsWithinDistInMap(u, i_range))
|
||||
return true;
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#define MIN_QUIET_DISTANCE 28.0f
|
||||
#define MAX_QUIET_DISTANCE 43.0f
|
||||
#define MIN_PATH_LENGTH 2.0f
|
||||
|
||||
template<class T>
|
||||
void FleeingMovementGenerator<T>::DoInitialize(T* owner)
|
||||
@@ -144,6 +145,20 @@ void FleeingMovementGenerator<T>::SetTargetLocation(T* owner)
|
||||
return;
|
||||
}
|
||||
|
||||
// Same position - recheck
|
||||
if (_path->getPathLength() < MIN_PATH_LENGTH)
|
||||
{
|
||||
if (_fleeTargetGUID)
|
||||
{
|
||||
++_shortPathsCount;
|
||||
}
|
||||
|
||||
_timer.Reset(100);
|
||||
return;
|
||||
}
|
||||
|
||||
_shortPathsCount = 0;
|
||||
|
||||
Movement::MoveSplineInit init(owner);
|
||||
init.MovebyPath(_path->GetPath());
|
||||
init.SetWalk(false);
|
||||
@@ -154,8 +169,13 @@ void FleeingMovementGenerator<T>::SetTargetLocation(T* owner)
|
||||
template<class T>
|
||||
void FleeingMovementGenerator<T>::GetPoint(T* owner, Position& position)
|
||||
{
|
||||
float casterDistance, casterAngle;
|
||||
if (Unit* fleeTarget = ObjectAccessor::GetUnit(*owner, _fleeTargetGUID))
|
||||
float casterDistance = 0.f;
|
||||
float casterAngle = 0.f;
|
||||
Unit* fleeTarget = nullptr;
|
||||
if (_shortPathsCount < 5)
|
||||
fleeTarget = ObjectAccessor::GetUnit(*owner, _fleeTargetGUID);
|
||||
|
||||
if (fleeTarget)
|
||||
{
|
||||
casterDistance = fleeTarget->GetDistance(owner);
|
||||
if (casterDistance > 0.2f)
|
||||
@@ -173,7 +193,8 @@ void FleeingMovementGenerator<T>::GetPoint(T* owner, Position& position)
|
||||
casterAngle = frand(0.0f, 2.0f * float(M_PI));
|
||||
}
|
||||
|
||||
float distance, angle;
|
||||
float distance = 0.f;
|
||||
float angle = 0.f;
|
||||
if (casterDistance < MIN_QUIET_DISTANCE)
|
||||
{
|
||||
distance = frand(0.4f, 1.3f) * (MIN_QUIET_DISTANCE - casterDistance);
|
||||
|
||||
@@ -24,7 +24,7 @@ template<class T>
|
||||
class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovementGenerator<T> >
|
||||
{
|
||||
public:
|
||||
explicit FleeingMovementGenerator(ObjectGuid fleeTargetGUID) : _path(nullptr), _fleeTargetGUID(fleeTargetGUID), _timer(0), _interrupt(false) {}
|
||||
explicit FleeingMovementGenerator(ObjectGuid fleeTargetGUID) : _path(nullptr), _fleeTargetGUID(fleeTargetGUID), _timer(0), _interrupt(false), _shortPathsCount(0) { }
|
||||
|
||||
MovementGeneratorType GetMovementGeneratorType() override { return FLEEING_MOTION_TYPE; }
|
||||
|
||||
@@ -41,6 +41,7 @@ class FleeingMovementGenerator : public MovementGeneratorMedium< T, FleeingMovem
|
||||
ObjectGuid _fleeTargetGUID;
|
||||
TimeTracker _timer;
|
||||
bool _interrupt;
|
||||
uint8 _shortPathsCount;
|
||||
};
|
||||
|
||||
class TimedFleeingMovementGenerator : public FleeingMovementGenerator<Creature>
|
||||
|
||||
@@ -5892,31 +5892,27 @@ SpellCastResult Spell::CheckCast(bool strict)
|
||||
if ((!m_caster->IsTotem() || !m_spellInfo->IsPositive()) && !m_spellInfo->HasAttribute(SPELL_ATTR2_IGNORE_LINE_OF_SIGHT) &&
|
||||
!m_spellInfo->HasAttribute(SPELL_ATTR5_ALWAYS_AOE_LINE_OF_SIGHT))
|
||||
{
|
||||
WorldObject* losCenter = nullptr;
|
||||
bool castedByGameobject = false;
|
||||
uint32 losChecks = LINEOFSIGHT_ALL_CHECKS;
|
||||
if (m_originalCasterGUID.IsGameObject())
|
||||
{
|
||||
losCenter = m_caster->GetMap()->GetGameObject(m_originalCasterGUID);
|
||||
castedByGameobject = m_caster->GetMap()->GetGameObject(m_originalCasterGUID) != nullptr;
|
||||
}
|
||||
else if (m_caster->GetEntry() == WORLD_TRIGGER)
|
||||
{
|
||||
if (TempSummon* tempSummon = m_caster->ToTempSummon())
|
||||
{
|
||||
losCenter = tempSummon->GetSummonerGameObject();
|
||||
castedByGameobject = tempSummon->GetSummonerGameObject() != nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (losCenter)
|
||||
if (castedByGameobject)
|
||||
{
|
||||
// If spell casted by gameobject then ignore M2 models
|
||||
losChecks &= ~LINEOFSIGHT_CHECK_GOBJECT_M2;
|
||||
}
|
||||
else
|
||||
{
|
||||
losCenter = m_caster;
|
||||
}
|
||||
|
||||
if (!losCenter->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks((losChecks))))
|
||||
if (!m_caster->IsWithinLOS(x, y, z, VMAP::ModelIgnoreFlags::M2, LineOfSightChecks((losChecks))))
|
||||
{
|
||||
return SPELL_FAILED_LINE_OF_SIGHT;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user