Core/Pets: ported a couple changes from 3.3.5 branch that went missing and corrected a master branch spell check that was allowing non-charmed player controlled units to bypass the ai movement check exception (pets are not meant to be charmed, only controlled)
This commit is contained in:
1 parent
2c38b2f4be
commit
924273363f
6 files changed
+27
-17
No files matched your search
@@ -412,7 +412,7 @@ Unit* PetAI::SelectNextTarget(bool allowAutoSelect) const
|
|||||||
if (me->HasReactState(REACT_AGGRESSIVE) && allowAutoSelect)
|
if (me->HasReactState(REACT_AGGRESSIVE) && allowAutoSelect)
|
||||||
{
|
{
|
||||||
if (!me->GetCharmInfo()->IsReturning() || me->GetCharmInfo()->IsFollowing() || me->GetCharmInfo()->IsAtStay())
|
if (!me->GetCharmInfo()->IsReturning() || me->GetCharmInfo()->IsFollowing() || me->GetCharmInfo()->IsAtStay())
|
||||||
if (Unit* nearTarget = me->SelectNearestHostileUnitInAggroRange(true))
|
if (Unit* nearTarget = me->SelectNearestHostileUnitInAggroRange(true, true))
|
||||||
return nearTarget;
|
return nearTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,7 +445,8 @@ void PetAI::HandleReturnMovement()
|
|||||||
me->GetCharmInfo()->GetStayPosition(x, y, z);
|
me->GetCharmInfo()->GetStayPosition(x, y, z);
|
||||||
ClearCharmInfoFlags();
|
ClearCharmInfoFlags();
|
||||||
me->GetCharmInfo()->SetIsReturning(true);
|
me->GetCharmInfo()->SetIsReturning(true);
|
||||||
me->GetMotionMaster()->Clear();
|
|
||||||
|
me->GetMotionMaster()->Clear(MOTION_SLOT_ACTIVE);
|
||||||
me->GetMotionMaster()->MovePoint(me->GetGUID().GetCounter(), x, y, z);
|
me->GetMotionMaster()->MovePoint(me->GetGUID().GetCounter(), x, y, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -455,7 +456,7 @@ void PetAI::HandleReturnMovement()
|
|||||||
{
|
{
|
||||||
ClearCharmInfoFlags();
|
ClearCharmInfoFlags();
|
||||||
me->GetCharmInfo()->SetIsReturning(true);
|
me->GetCharmInfo()->SetIsReturning(true);
|
||||||
me->GetMotionMaster()->Clear();
|
me->GetMotionMaster()->Clear(MOTION_SLOT_ACTIVE);
|
||||||
me->FollowTarget(me->GetCharmerOrOwner());
|
me->FollowTarget(me->GetCharmerOrOwner());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -481,7 +482,7 @@ void PetAI::DoAttack(Unit* target, bool chase)
|
|||||||
bool oldCmdAttack = me->GetCharmInfo()->IsCommandAttack(); // This needs to be reset after other flags are cleared
|
bool oldCmdAttack = me->GetCharmInfo()->IsCommandAttack(); // This needs to be reset after other flags are cleared
|
||||||
ClearCharmInfoFlags();
|
ClearCharmInfoFlags();
|
||||||
me->GetCharmInfo()->SetIsCommandAttack(oldCmdAttack); // For passive pets commanded to attack so they will use spells
|
me->GetCharmInfo()->SetIsCommandAttack(oldCmdAttack); // For passive pets commanded to attack so they will use spells
|
||||||
me->GetMotionMaster()->Clear();
|
me->GetMotionMaster()->Clear(MOTION_SLOT_ACTIVE);
|
||||||
|
|
||||||
float chaseDistance = me->GetPetChaseDistance();
|
float chaseDistance = me->GetPetChaseDistance();
|
||||||
|
|
||||||
@@ -494,26 +495,25 @@ void PetAI::DoAttack(Unit* target, bool chase)
|
|||||||
{
|
{
|
||||||
ClearCharmInfoFlags();
|
ClearCharmInfoFlags();
|
||||||
me->GetCharmInfo()->SetIsAtStay(true);
|
me->GetCharmInfo()->SetIsAtStay(true);
|
||||||
me->GetMotionMaster()->Clear();
|
me->GetMotionMaster()->Clear(MOTION_SLOT_ACTIVE);
|
||||||
me->GetMotionMaster()->MoveIdle();
|
me->GetMotionMaster()->MoveIdle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void PetAI::MovementInform(uint32 moveType, uint32 data)
|
void PetAI::MovementInform(uint32 type, uint32 id)
|
||||||
{
|
{
|
||||||
// Receives notification when pet reaches stay or follow owner
|
// Receives notification when pet reaches stay or follow owner
|
||||||
switch (moveType)
|
switch (type)
|
||||||
{
|
{
|
||||||
case POINT_MOTION_TYPE:
|
case POINT_MOTION_TYPE:
|
||||||
{
|
{
|
||||||
// Pet is returning to where stay was clicked. data should be
|
// Pet is returning to where stay was clicked. data should be
|
||||||
// pet's GUIDLow since we set that as the waypoint ID
|
// pet's GUIDLow since we set that as the waypoint ID
|
||||||
if (data == me->GetGUID().GetCounter() && me->GetCharmInfo()->IsReturning())
|
if (id == me->GetGUID().GetCounter() && me->GetCharmInfo()->IsReturning())
|
||||||
{
|
{
|
||||||
ClearCharmInfoFlags();
|
ClearCharmInfoFlags();
|
||||||
me->GetCharmInfo()->SetIsAtStay(true);
|
me->GetCharmInfo()->SetIsAtStay(true);
|
||||||
me->GetMotionMaster()->Clear();
|
|
||||||
me->GetMotionMaster()->MoveIdle();
|
me->GetMotionMaster()->MoveIdle();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -522,7 +522,7 @@ void PetAI::MovementInform(uint32 moveType, uint32 data)
|
|||||||
{
|
{
|
||||||
// If data is owner's GUIDLow then we've reached follow point,
|
// If data is owner's GUIDLow then we've reached follow point,
|
||||||
// otherwise we're probably chasing a creature
|
// otherwise we're probably chasing a creature
|
||||||
if (me->GetCharmerOrOwner() && me->GetCharmInfo() && data == me->GetCharmerOrOwner()->GetGUID().GetCounter() && me->GetCharmInfo()->IsReturning())
|
if (me->GetCharmerOrOwner() && me->GetCharmInfo() && id == me->GetCharmerOrOwner()->GetGUID().GetCounter() && me->GetCharmInfo()->IsReturning())
|
||||||
{
|
{
|
||||||
ClearCharmInfoFlags();
|
ClearCharmInfoFlags();
|
||||||
me->GetCharmInfo()->SetIsFollowing(true);
|
me->GetCharmInfo()->SetIsFollowing(true);
|
||||||
@@ -624,7 +624,7 @@ void PetAI::ReceiveEmote(Player* player, uint32 emote)
|
|||||||
|
|
||||||
void PetAI::OnCharmed(bool isNew)
|
void PetAI::OnCharmed(bool isNew)
|
||||||
{
|
{
|
||||||
if (me->IsCharmed())
|
if (!me->isPossessedByPlayer() && me->IsCharmed())
|
||||||
me->FollowTarget(me->GetCharmer());
|
me->FollowTarget(me->GetCharmer());
|
||||||
|
|
||||||
CreatureAI::OnCharmed(isNew);
|
CreatureAI::OnCharmed(isNew);
|
||||||
|
|||||||
@@ -38,11 +38,13 @@ class TC_GAME_API PetAI : public CreatureAI
|
|||||||
void KilledUnit(Unit* /*victim*/) override;
|
void KilledUnit(Unit* /*victim*/) override;
|
||||||
void AttackStart(Unit* target) override; // only start attacking if not attacking something else already
|
void AttackStart(Unit* target) override; // only start attacking if not attacking something else already
|
||||||
void _AttackStart(Unit* target); // always start attacking if possible
|
void _AttackStart(Unit* target); // always start attacking if possible
|
||||||
void MovementInform(uint32 moveType, uint32 data) override;
|
void MovementInform(uint32 type, uint32 id) override;
|
||||||
void OwnerAttackedBy(Unit* attacker) override;
|
void OwnerAttackedBy(Unit* attacker) override;
|
||||||
void OwnerAttacked(Unit* target) override;
|
void OwnerAttacked(Unit* target) override;
|
||||||
void DamageTaken(Unit* attacker, uint32& /*damage*/) override { AttackStart(attacker); }
|
void DamageTaken(Unit* attacker, uint32& /*damage*/) override { AttackStart(attacker); }
|
||||||
void ReceiveEmote(Player* player, uint32 textEmote) override;
|
void ReceiveEmote(Player* player, uint32 textEmote) override;
|
||||||
|
void JustEnteredCombat(Unit* who) override { EngagementStart(who); }
|
||||||
|
void JustExitedCombat() override { EngagementOver(); }
|
||||||
void OnCharmed(bool isNew) override;
|
void OnCharmed(bool isNew) override;
|
||||||
|
|
||||||
// The following aren't used by the PetAI but need to be defined to override
|
// The following aren't used by the PetAI but need to be defined to override
|
||||||
|
|||||||
@@ -3000,14 +3000,14 @@ float Creature::GetAggroRange(Unit const* target) const
|
|||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Unit* Creature::SelectNearestHostileUnitInAggroRange(bool useLOS) const
|
Unit* Creature::SelectNearestHostileUnitInAggroRange(bool useLOS, bool ignoreCivilians) const
|
||||||
{
|
{
|
||||||
// Selects nearest hostile target within creature's aggro range. Used primarily by
|
// Selects nearest hostile target within creature's aggro range. Used primarily by
|
||||||
// pets set to aggressive. Will not return neutral or friendly targets.
|
// pets set to aggressive. Will not return neutral or friendly targets.
|
||||||
|
|
||||||
Unit* target = nullptr;
|
Unit* target = nullptr;
|
||||||
|
|
||||||
Trinity::NearestHostileUnitInAggroRangeCheck u_check(this, useLOS);
|
Trinity::NearestHostileUnitInAggroRangeCheck u_check(this, useLOS, ignoreCivilians);
|
||||||
Trinity::UnitSearcher<Trinity::NearestHostileUnitInAggroRangeCheck> searcher(this, target, u_check);
|
Trinity::UnitSearcher<Trinity::NearestHostileUnitInAggroRangeCheck> searcher(this, target, u_check);
|
||||||
|
|
||||||
Cell::VisitGridObjects(this, searcher, MAX_AGGRO_RADIUS);
|
Cell::VisitGridObjects(this, searcher, MAX_AGGRO_RADIUS);
|
||||||
|
|||||||
@@ -241,7 +241,7 @@ class TC_GAME_API Creature : public Unit, public GridObject<Creature>, public Ma
|
|||||||
|
|
||||||
Unit* SelectNearestTarget(float dist = 0, bool playerOnly = false) const;
|
Unit* SelectNearestTarget(float dist = 0, bool playerOnly = false) const;
|
||||||
Unit* SelectNearestTargetInAttackDistance(float dist = 0) const;
|
Unit* SelectNearestTargetInAttackDistance(float dist = 0) const;
|
||||||
Unit* SelectNearestHostileUnitInAggroRange(bool useLOS = false) const;
|
Unit* SelectNearestHostileUnitInAggroRange(bool useLOS = false, bool ignoreCivilians = false) const;
|
||||||
|
|
||||||
void DoFleeToGetAssistance();
|
void DoFleeToGetAssistance();
|
||||||
void CallForHelp(float fRadius);
|
void CallForHelp(float fRadius);
|
||||||
|
|||||||
@@ -1217,9 +1217,10 @@ namespace Trinity
|
|||||||
class NearestHostileUnitInAggroRangeCheck
|
class NearestHostileUnitInAggroRangeCheck
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit NearestHostileUnitInAggroRangeCheck(Creature const* creature, bool useLOS = false) : _me(creature), _useLOS(useLOS)
|
explicit NearestHostileUnitInAggroRangeCheck(Creature const* creature, bool useLOS = false, bool ignoreCivilians = false) : _me(creature), _useLOS(useLOS), _ignoreCivilians(ignoreCivilians)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator()(Unit* u)
|
bool operator()(Unit* u)
|
||||||
{
|
{
|
||||||
if (!u->IsHostileTo(_me))
|
if (!u->IsHostileTo(_me))
|
||||||
@@ -1234,12 +1235,19 @@ namespace Trinity
|
|||||||
if (_useLOS && !u->IsWithinLOSInMap(_me))
|
if (_useLOS && !u->IsWithinLOSInMap(_me))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
// pets in aggressive do not attack civilians
|
||||||
|
if (_ignoreCivilians)
|
||||||
|
if (Creature* c = u->ToCreature())
|
||||||
|
if (c->IsCivilian())
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Creature const* _me;
|
Creature const* _me;
|
||||||
bool _useLOS;
|
bool _useLOS;
|
||||||
|
bool _ignoreCivilians;
|
||||||
NearestHostileUnitInAggroRangeCheck(NearestHostileUnitInAggroRangeCheck const&);
|
NearestHostileUnitInAggroRangeCheck(NearestHostileUnitInAggroRangeCheck const&);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -4093,7 +4093,7 @@ void Spell::update(uint32 difftime)
|
|||||||
// if charmed by creature, trust the AI not to cheat and allow the cast to proceed
|
// if charmed by creature, trust the AI not to cheat and allow the cast to proceed
|
||||||
// @todo this is a hack, "creature" movesplines don't differentiate turning/moving right now
|
// @todo this is a hack, "creature" movesplines don't differentiate turning/moving right now
|
||||||
// however, checking what type of movement the spline is for every single spline would be really expensive
|
// however, checking what type of movement the spline is for every single spline would be really expensive
|
||||||
if (!m_caster->ToUnit()->GetCharmerGUID().IsCreature())
|
if (!m_caster->ToUnit()->IsControlledByPlayer())
|
||||||
cancel();
|
cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user