[Loot] 50% player damage to mob reuired for reward

Unchanged TC backport. Not fully tested.
This commit is contained in:
Olion 2015-10-01 21:52:25 +03:00 committed by Antz
parent 1b8c8209a7
commit 98dfabe70b
7 changed files with 49 additions and 13 deletions

View File

@ -150,7 +150,7 @@ Creature::Creature(CreatureSubtype subtype) : Unit(),
m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false),
m_AI_locked(false), m_IsDeadByDefault(false), m_temporaryFactionFlags(TEMPFACTION_NONE),
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0),
m_creatureInfo(NULL)
m_creatureInfo(NULL), m_PlayerDamageReq(0)
{
/* Loot data */
hasBeenLootedOnce = false;
@ -1251,6 +1251,8 @@ void Creature::SelectLevel(const CreatureInfo* cinfo, float percentHealth /*= 10
else
{ SetHealthPercent(percentHealth); }
ResetPlayerDamageReq();
SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, float(health));
// all power types
@ -1335,6 +1337,12 @@ float Creature::_GetDamageMod(int32 Rank)
}
}
void Creature::LowerPlayerDamageReq(uint32 unDamage)
{
if (m_PlayerDamageReq)
m_PlayerDamageReq > unDamage ? m_PlayerDamageReq -= unDamage : m_PlayerDamageReq = 0;
}
float Creature::_GetSpellDamageMod(int32 Rank)
{
switch (Rank) // define rates for each elite rank
@ -1651,6 +1659,7 @@ void Creature::SetDeathState(DeathState s)
// Dynamic flags must be set on Tapped by default.
SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
LoadCreatureAddon(true);
ResetPlayerDamageReq();
// Flags after LoadCreatureAddon. Any spell in *addon
// will not be able to adjust these.

View File

@ -684,6 +684,9 @@ class Creature : public Unit
Player* GetLootRecipient() const; // use group cases as prefered
Group* GetGroupLootRecipient() const;
bool IsTappedBy(Player const* player) const;
bool IsDamageEnoughForLootingAndReward() const { return m_PlayerDamageReq == 0; }
void LowerPlayerDamageReq(uint32 unDamage);
void ResetPlayerDamageReq() { m_PlayerDamageReq = GetHealth() / 2; }
/**
* function indicating whether the whether the creature has a looter recipient defined (either a group ID, either a player GUID).
@ -842,6 +845,7 @@ class Creature : public Unit
MovementGeneratorType m_defaultMovementType;
Cell m_currentCell; // store current cell where creature listed
uint32 m_equipmentId;
uint32 m_PlayerDamageReq;
// below fields has potential for optimization
bool m_AlreadyCallAssistance;

View File

@ -147,7 +147,7 @@ class CreatureAI
* Called for reaction at stopping attack at no attackers or targets
* This is called usually in Unit::SelectHostileTarget, if no more target exists
*/
virtual void EnterEvadeMode() {}
virtual void EnterEvadeMode() { m_creature->ResetPlayerDamageReq(); }
/**
* Called at reaching home after MoveTargetedHome

View File

@ -1163,6 +1163,7 @@ void CreatureEventAI::EnterEvadeMode()
if (i->Event.event_type == EVENT_T_EVADE)
{ ProcessEvent(*i); }
}
m_creature->ResetPlayerDamageReq();
}
void CreatureEventAI::JustDied(Unit* killer)

View File

@ -14071,8 +14071,8 @@ bool Player::IsTappedByMeOrMyGroup(Creature* creature)
* Called from Object::BuildValuesUpdate */
bool Player::isAllowedToLoot(Creature* creature)
{
/* Nobody tapped the monster (solo kill by another NPC) */
if (!creature->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED))
/* Nobody tapped the monster (kill either solo or mostly by another NPC) */
if (!creature->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED) || !creature->IsDamageEnoughForLootingAndReward())
{ return false; }
/* If we there is a loot recipient, assign it to recipient */

View File

@ -631,8 +631,14 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa
{ SetContestedPvP(attackedPlayer); }
}
if (pVictim->GetTypeId() == TYPEID_UNIT && !((Creature*)pVictim)->IsPet() && !((Creature*)pVictim)->HasLootRecipient())
{ ((Creature*)pVictim)->SetLootRecipient(this); }
if (Creature* victim = pVictim->ToCreature())
{
if (!victim->IsPet() && !victim->HasLootRecipient())
victim->SetLootRecipient(this);
if (IsControlledByPlayer()) // more narrow: IsPet(), IsGuardian() ?
victim->LowerPlayerDamageReq(health < damage ? health : damage);
}
if (health <= damage)
{
@ -681,23 +687,36 @@ uint32 Unit::DealDamage(Unit* pVictim, uint32 damage, CleanDamage const* cleanDa
/*
* Generic Actions (ProcEvents, Combat-Log, Kill Rewards, Stop Combat)
*/
bool isRewardAllowed = true;
if (Creature* creature = pVictim->ToCreature())
{
isRewardAllowed = creature->IsDamageEnoughForLootingAndReward();
if (!isRewardAllowed)
creature->SetLootRecipient(NULL);
}
// call kill spell proc event (before real die and combat stop to triggering auras removed at death/combat stop)
if (player_tap && player_tap != pVictim)
{
player_tap->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
WorldPacket data(SMSG_PARTYKILLLOG, (8 + 8)); // send event PARTY_KILL
data << player_tap->GetObjectGuid(); // player with killing blow
data << pVictim->GetObjectGuid(); // victim
if (isRewardAllowed)
{
WorldPacket data(SMSG_PARTYKILLLOG, (8 + 8)); // send event PARTY_KILL
data << player_tap->GetObjectGuid(); // player with killing blow
data << pVictim->GetObjectGuid(); // victim
if (group_tap)
{ group_tap->BroadcastPacket(&data, false, group_tap->GetMemberGroup(player_tap->GetObjectGuid()), player_tap->GetObjectGuid()); }
if (group_tap)
{
group_tap->BroadcastPacket(&data, false, group_tap->GetMemberGroup(player_tap->GetObjectGuid()), player_tap->GetObjectGuid());
}
player_tap->SendDirectMessage(&data);
player_tap->SendDirectMessage(&data);
}
}
// Reward player, his pets, and group/raid members
if (player_tap != pVictim)
if (isRewardAllowed && player_tap != pVictim)
{
if (group_tap)
{ group_tap->RewardGroupAtKill(pVictim, player_tap); }

View File

@ -962,6 +962,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
{
DoSpellHitOnUnit(m_caster, mask, true);
unitTarget = m_caster;
if (m_caster->GetTypeId() == TYPEID_UNIT)
m_caster->ToCreature()->LowerPlayerDamageReq(target->damage);
}
}
else // in 1.12.1 we need explicit miss info