[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_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false),
m_AI_locked(false), m_IsDeadByDefault(false), m_temporaryFactionFlags(TEMPFACTION_NONE), m_AI_locked(false), m_IsDeadByDefault(false), m_temporaryFactionFlags(TEMPFACTION_NONE),
m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL), m_originalEntry(0),
m_creatureInfo(NULL) m_creatureInfo(NULL), m_PlayerDamageReq(0)
{ {
/* Loot data */ /* Loot data */
hasBeenLootedOnce = false; hasBeenLootedOnce = false;
@ -1251,6 +1251,8 @@ void Creature::SelectLevel(const CreatureInfo* cinfo, float percentHealth /*= 10
else else
{ SetHealthPercent(percentHealth); } { SetHealthPercent(percentHealth); }
ResetPlayerDamageReq();
SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, float(health)); SetModifierValue(UNIT_MOD_HEALTH, BASE_VALUE, float(health));
// all power types // 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) float Creature::_GetSpellDamageMod(int32 Rank)
{ {
switch (Rank) // define rates for each elite 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. // Dynamic flags must be set on Tapped by default.
SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE); SetUInt32Value(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_NONE);
LoadCreatureAddon(true); LoadCreatureAddon(true);
ResetPlayerDamageReq();
// Flags after LoadCreatureAddon. Any spell in *addon // Flags after LoadCreatureAddon. Any spell in *addon
// will not be able to adjust these. // 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 Player* GetLootRecipient() const; // use group cases as prefered
Group* GetGroupLootRecipient() const; Group* GetGroupLootRecipient() const;
bool IsTappedBy(Player const* player) 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). * 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; MovementGeneratorType m_defaultMovementType;
Cell m_currentCell; // store current cell where creature listed Cell m_currentCell; // store current cell where creature listed
uint32 m_equipmentId; uint32 m_equipmentId;
uint32 m_PlayerDamageReq;
// below fields has potential for optimization // below fields has potential for optimization
bool m_AlreadyCallAssistance; bool m_AlreadyCallAssistance;

View File

@ -147,7 +147,7 @@ class CreatureAI
* Called for reaction at stopping attack at no attackers or targets * Called for reaction at stopping attack at no attackers or targets
* This is called usually in Unit::SelectHostileTarget, if no more target exists * 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 * Called at reaching home after MoveTargetedHome

View File

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

View File

@ -14071,8 +14071,8 @@ bool Player::IsTappedByMeOrMyGroup(Creature* creature)
* Called from Object::BuildValuesUpdate */ * Called from Object::BuildValuesUpdate */
bool Player::isAllowedToLoot(Creature* creature) bool Player::isAllowedToLoot(Creature* creature)
{ {
/* Nobody tapped the monster (solo kill by another NPC) */ /* Nobody tapped the monster (kill either solo or mostly by another NPC) */
if (!creature->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED)) if (!creature->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED) || !creature->IsDamageEnoughForLootingAndReward())
{ return false; } { return false; }
/* If we there is a loot recipient, assign it to recipient */ /* 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); } { SetContestedPvP(attackedPlayer); }
} }
if (pVictim->GetTypeId() == TYPEID_UNIT && !((Creature*)pVictim)->IsPet() && !((Creature*)pVictim)->HasLootRecipient()) if (Creature* victim = pVictim->ToCreature())
{ ((Creature*)pVictim)->SetLootRecipient(this); } {
if (!victim->IsPet() && !victim->HasLootRecipient())
victim->SetLootRecipient(this);
if (IsControlledByPlayer()) // more narrow: IsPet(), IsGuardian() ?
victim->LowerPlayerDamageReq(health < damage ? health : damage);
}
if (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) * 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) // 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) if (player_tap && player_tap != pVictim)
{ {
player_tap->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0); player_tap->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
WorldPacket data(SMSG_PARTYKILLLOG, (8 + 8)); // send event PARTY_KILL if (isRewardAllowed)
data << player_tap->GetObjectGuid(); // player with killing blow {
data << pVictim->GetObjectGuid(); // victim 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) if (group_tap)
{ group_tap->BroadcastPacket(&data, false, group_tap->GetMemberGroup(player_tap->GetObjectGuid()), player_tap->GetObjectGuid()); } {
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 // Reward player, his pets, and group/raid members
if (player_tap != pVictim) if (isRewardAllowed && player_tap != pVictim)
{ {
if (group_tap) if (group_tap)
{ group_tap->RewardGroupAtKill(pVictim, player_tap); } { group_tap->RewardGroupAtKill(pVictim, player_tap); }

View File

@ -962,6 +962,9 @@ void Spell::DoAllEffectOnTarget(TargetInfo* target)
{ {
DoSpellHitOnUnit(m_caster, mask, true); DoSpellHitOnUnit(m_caster, mask, true);
unitTarget = m_caster; 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 else // in 1.12.1 we need explicit miss info