Merge branch 'azerothcore:master' into Playerbot

This commit is contained in:
ZhengPeiRu21
2022-06-08 11:10:38 -06:00
committed by GitHub
32 changed files with 2341 additions and 744 deletions

View File

@@ -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);

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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);

View File

@@ -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>

View File

@@ -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;
}