mirror of
https://github.com/azerothcore/azerothcore-wotlk.git
synced 2025-11-10 12:24:22 +08:00
Merge cd4dfa2166b223a4ead351869d791a958e0379b2 into 5bef92d5eaca3e2ecc317f9d599312bc23eb71aa
This commit is contained in:
commit
7ae6db02ad
@ -185,7 +185,7 @@ void CreatureAI::MoveInLineOfSight(Unit* who)
|
||||
!me->IsWithinDist(who, ATTACK_DISTANCE, true, false, false)) // if in combat and in dist - neutral to all can actually assist other creatures
|
||||
return;
|
||||
|
||||
if (me->HasReactState(REACT_AGGRESSIVE) && me->CanStartAttack(who))
|
||||
if (me->HasReactState(REACT_AGGRESSIVE) && me->CanStartAttack(who) && (me->IsAggroGracePeriodExpired() || me->GetMap()->Instanceable()))
|
||||
AttackStart(who);
|
||||
}
|
||||
|
||||
|
||||
@ -274,7 +274,7 @@ Creature::Creature(): Unit(), MovableMapObject(), m_groupLootTimer(0), lootingGr
|
||||
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_combatPulseTime(0), m_combatPulseDelay(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
|
||||
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_alreadyCallForHelp(false), m_AlreadyCallAssistance(false),
|
||||
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_regenPower(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_moveInLineOfSightDisabled(false), m_moveInLineOfSightStrictlyDisabled(false),
|
||||
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f),_sparringPct(0.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), m_lastLeashExtensionTime(nullptr), m_cannotReachTimer(0),
|
||||
m_homePosition(), m_transportHomePosition(), m_creatureInfo(nullptr), m_creatureData(nullptr), m_detectionDistance(20.0f),_sparringPct(0.0f), m_waypointID(0), m_path_id(0), m_formation(nullptr), _aggroGracePeriodExpired(false), m_lastLeashExtensionTime(nullptr), m_cannotReachTimer(0),
|
||||
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false), _isCombatMovementAllowed(true)
|
||||
{
|
||||
m_regenTimer = CREATURE_REGEN_INTERVAL;
|
||||
@ -944,6 +944,21 @@ void Creature::Update(uint32 diff)
|
||||
}
|
||||
}
|
||||
|
||||
void Creature::Heartbeat()
|
||||
{
|
||||
Unit::Heartbeat();
|
||||
|
||||
// creatures should only attack surroundings initially after heartbeat has passed or until attacked
|
||||
if (!_aggroGracePeriodExpired)
|
||||
{
|
||||
_aggroGracePeriodExpired = true;
|
||||
|
||||
// trigger MoveInLineOfSight
|
||||
Acore::CreatureAggroGracePeriodExpiredNotifier notifier(*this);
|
||||
Cell::VisitObjects(this, notifier, GetVisibilityRange());
|
||||
}
|
||||
}
|
||||
|
||||
bool Creature::IsFreeToMove()
|
||||
{
|
||||
uint32 moveFlags = m_movementInfo.GetMovementFlags();
|
||||
@ -2654,12 +2669,6 @@ bool Creature::CanCreatureAttack(Unit const* victim, bool skipDistCheck) const
|
||||
if (victim->IsCreature() && victim->ToCreature()->IsInEvadeMode())
|
||||
return false;
|
||||
|
||||
// cannot attack if is during 5 second grace period, unless being attacked
|
||||
if (m_respawnedTime && (GameTime::GetGameTime().count() - m_respawnedTime) < 5 && !IsEngagedBy(victim))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// if victim is in FD and we can't see that
|
||||
if (victim->HasUnitFlag2(UNIT_FLAG2_FEIGN_DEATH) && !CanIgnoreFeignDeath())
|
||||
{
|
||||
|
||||
@ -69,6 +69,8 @@ public:
|
||||
[[nodiscard]] ObjectGuid::LowType GetSpawnId() const { return m_spawnId; }
|
||||
|
||||
void Update(uint32 time) override; // overwrited Unit::Update
|
||||
void Heartbeat() override;
|
||||
|
||||
void GetRespawnPosition(float& x, float& y, float& z, float* ori = nullptr, float* dist = nullptr) const;
|
||||
|
||||
void SetCorpseDelay(uint32 delay) { m_corpseDelay = delay; }
|
||||
@ -187,6 +189,8 @@ public:
|
||||
void UpdateAttackPowerAndDamage(bool ranged = false) override;
|
||||
void CalculateMinMaxDamage(WeaponAttackType attType, bool normalized, bool addTotalPct, float& minDamage, float& maxDamage, uint8 damageIndex) override;
|
||||
|
||||
bool IsAggroGracePeriodExpired() { return _aggroGracePeriodExpired; }
|
||||
|
||||
void LoadSparringPct();
|
||||
[[nodiscard]] float GetSparringPct() const { return _sparringPct; }
|
||||
|
||||
@ -516,6 +520,8 @@ private:
|
||||
CreatureGroup* m_formation;
|
||||
bool TriggerJustRespawned;
|
||||
|
||||
bool _aggroGracePeriodExpired;
|
||||
|
||||
// Shared timer between mobs who assist another.
|
||||
// Damaging one extends leash range on all of them.
|
||||
mutable std::shared_ptr<time_t> m_lastLeashExtensionTime;
|
||||
|
||||
@ -186,6 +186,25 @@ void AIRelocationNotifier::Visit(CreatureMapType& m)
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureAggroGracePeriodExpiredNotifier::Visit(CreatureMapType& m)
|
||||
{
|
||||
for (CreatureMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Creature* c = iter->GetSource();
|
||||
CreatureUnitRelocationWorker(c, &i_creature);
|
||||
CreatureUnitRelocationWorker(&i_creature, c);
|
||||
}
|
||||
}
|
||||
|
||||
void CreatureAggroGracePeriodExpiredNotifier::Visit(PlayerMapType& m)
|
||||
{
|
||||
for (PlayerMapType::iterator iter = m.begin(); iter != m.end(); ++iter)
|
||||
{
|
||||
Player* player = iter->GetSource();
|
||||
CreatureUnitRelocationWorker(&i_creature, player);
|
||||
}
|
||||
}
|
||||
|
||||
// Uses visibility map
|
||||
void MessageDistDeliverer::Visit(VisiblePlayersMap const& m)
|
||||
{
|
||||
|
||||
@ -96,6 +96,14 @@ namespace Acore
|
||||
void Visit(CreatureMapType&);
|
||||
};
|
||||
|
||||
struct CreatureAggroGracePeriodExpiredNotifier
|
||||
{
|
||||
Creature& i_creature;
|
||||
CreatureAggroGracePeriodExpiredNotifier(Creature& c) : i_creature(c) {}
|
||||
template<class T> void Visit(GridRefMgr<T>&) {}
|
||||
void Visit(CreatureMapType&);
|
||||
void Visit(PlayerMapType&);
|
||||
};
|
||||
struct MessageDistDeliverer
|
||||
{
|
||||
WorldObject const* i_source;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user