fix(Core/Pets): Mob "soloed" by pet should not grant exp/loot to its … (#11969)

* fix(Core/Pets): Mob "soloed" by pet should not grant exp/loot to its master.

Fixes #11528
This commit is contained in:
UltraNix
2022-06-19 13:46:23 +02:00
committed by GitHub
parent 82cfd1b8d4
commit a935e51754
4 changed files with 45 additions and 16 deletions

View File

@@ -215,13 +215,13 @@ bool TemporaryThreatModifierEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
return true;
}
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(), m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0), m_lootRecipientGroup(0),
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MovableMapObject(), m_groupLootTimer(0), lootingGroupLowGUID(0), m_lootRecipientGroup(0),
m_corpseRemoveTime(0), m_respawnTime(0), m_respawnDelay(300), m_corpseDelay(60), m_wanderDistance(0.0f), m_boundaryCheckTime(2500),
m_transportCheckTimer(1000), lootPickPocketRestoreTime(0), m_reactState(REACT_AGGRESSIVE), m_defaultMovementType(IDLE_MOTION_TYPE),
m_spawnId(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(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), m_waypointID(0), m_path_id(0), m_formation(nullptr), _lastDamagedTime(nullptr), m_cannotReachTarget(false), m_cannotReachTimer(0),
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0)
_isMissingSwimmingFlagOutOfCombat(false), m_assistanceTimer(0), _playerDamageReq(0), _damagedByPlayer(false)
{
m_regenTimer = CREATURE_REGEN_INTERVAL;
m_valuesCount = UNIT_END;
@@ -526,7 +526,7 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele
uint32 previousHealth = GetHealth();
uint32 previousMaxHealth = GetMaxHealth();
uint32 previousPlayerDamageReq = m_PlayerDamageReq;
uint32 previousPlayerDamageReq = _playerDamageReq;
SelectLevel(changelevel);
if (previousHealth > 0)
@@ -535,11 +535,11 @@ bool Creature::UpdateEntry(uint32 Entry, const CreatureData* data, bool changele
if (previousMaxHealth && previousMaxHealth > GetMaxHealth())
{
m_PlayerDamageReq = (uint32)(previousPlayerDamageReq * GetMaxHealth() / previousMaxHealth);
_playerDamageReq = (uint32)(previousPlayerDamageReq * GetMaxHealth() / previousMaxHealth);
}
else
{
m_PlayerDamageReq = previousPlayerDamageReq;
_playerDamageReq = previousPlayerDamageReq;
}
}
@@ -3573,3 +3573,30 @@ void Creature::ModifyThreatPercentTemp(Unit* victim, int32 percent, Milliseconds
m_Events.AddEvent(pEvent, m_Events.CalculateTime(duration.count()));
}
}
bool Creature::IsDamageEnoughForLootingAndReward() const
{
return (m_creatureInfo->flags_extra & CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ) || (_playerDamageReq == 0 && _damagedByPlayer);
}
void Creature::LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer /*= true*/)
{
if (_playerDamageReq)
_playerDamageReq > unDamage ? _playerDamageReq -= unDamage : _playerDamageReq = 0;
if (!_damagedByPlayer)
{
_damagedByPlayer = damagedByPlayer;
}
}
void Creature::ResetPlayerDamageReq()
{
_playerDamageReq = GetHealth() / 2;
_damagedByPlayer = false;
}
uint32 Creature::GetPlayerDamageReq() const
{
return _playerDamageReq;
}

View File

@@ -341,14 +341,10 @@ public:
void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; }
[[nodiscard]] bool IsReputationGainDisabled() const { return DisableReputationGain; }
[[nodiscard]] bool IsDamageEnoughForLootingAndReward() const { return (m_creatureInfo->flags_extra & CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ) || (m_PlayerDamageReq == 0); }
void LowerPlayerDamageReq(uint32 unDamage)
{
if (m_PlayerDamageReq)
m_PlayerDamageReq > unDamage ? m_PlayerDamageReq -= unDamage : m_PlayerDamageReq = 0;
}
void ResetPlayerDamageReq() { m_PlayerDamageReq = GetHealth() / 2; }
uint32 m_PlayerDamageReq;
[[nodiscard]] bool IsDamageEnoughForLootingAndReward() const;
void LowerPlayerDamageReq(uint32 unDamage, bool damagedByPlayer = true);
void ResetPlayerDamageReq();
[[nodiscard]] uint32 GetPlayerDamageReq() const;
[[nodiscard]] uint32 GetOriginalEntry() const { return m_originalEntry; }
void SetOriginalEntry(uint32 entry) { m_originalEntry = entry; }
@@ -470,6 +466,8 @@ private:
uint32 m_assistanceTimer;
uint32 _playerDamageReq;
bool _damagedByPlayer;
};
class AssistDelayEvent : public BasicEvent

View File

@@ -999,7 +999,11 @@ uint32 Unit::DealDamage(Unit* attacker, Unit* victim, uint32 damage, CleanDamage
victim->ToCreature()->SetLootRecipient(attacker);
if (!attacker || attacker->IsControlledByPlayer() || attacker->IsCreatedByPlayer())
victim->ToCreature()->LowerPlayerDamageReq(health < damage ? health : damage);
{
uint32 unDamage = health < damage ? health : damage;
bool damagedByPlayer = unDamage && attacker && attacker->m_movedByPlayer != nullptr;
victim->ToCreature()->LowerPlayerDamageReq(unDamage, damagedByPlayer);
}
}
if (health <= damage)

View File

@@ -124,9 +124,9 @@ uint32 Acore::XP::Gain(Player* player, Unit* unit, bool isBattleGround /*= false
}
// if players dealt less than 50% of the damage and were credited anyway (due to CREATURE_FLAG_EXTRA_NO_PLAYER_DAMAGE_REQ), scale XP gained appropriately (linear scaling)
if (creature && creature->m_PlayerDamageReq)
if (creature && creature->GetPlayerDamageReq())
{
xpMod *= 1.0f - 2.0f * creature->m_PlayerDamageReq / creature->GetMaxHealth();
xpMod *= 1.0f - 2.0f * creature->GetPlayerDamageReq() / creature->GetMaxHealth();
}
gain = uint32(gain * xpMod);