mirror of
https://github.com/araxiaonline/TrinityCore2.git
synced 2026-06-19 06:19:38 -04:00
Core/Mechanics: refactor XP (and in fact, honor/reputation/kill credit) rewarding routine and get rid of copy/pasted code.
This commit is contained in:
@@ -1949,91 +1949,8 @@ void Battleground::SetBracket(PvPDifficultyEntry const* bracketEntry)
|
||||
SetLevelRange(bracketEntry->minLevel,bracketEntry->maxLevel);
|
||||
}
|
||||
|
||||
void Battleground::RewardXPAtKill(Player* plr, Player* victim)
|
||||
void Battleground::RewardXPAtKill(Player* killer, Player* victim)
|
||||
{
|
||||
if (!sWorld->getBoolConfig(CONFIG_BG_XP_FOR_KILL) || !plr || !victim)
|
||||
return;
|
||||
|
||||
uint32 xp = 0;
|
||||
Player* member_with_max_level = NULL;
|
||||
Player* not_gray_member_with_max_level = NULL;
|
||||
|
||||
if (Group *pGroup = plr->GetGroup())//should be always in a raid group while in any bg
|
||||
{
|
||||
uint32 count = 0;
|
||||
uint32 sum_level = 0;
|
||||
for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player* member = itr->getSource();
|
||||
if (!member || !member->isAlive()) // only for alive
|
||||
continue;
|
||||
|
||||
if (!member->IsAtGroupRewardDistance(victim)) // at req. distance
|
||||
continue;
|
||||
|
||||
++count;
|
||||
sum_level += member->getLevel();
|
||||
if (!member_with_max_level || member_with_max_level->getLevel() < member->getLevel())
|
||||
member_with_max_level = member;
|
||||
|
||||
uint32 gray_level = Trinity::XP::GetGrayLevel(member->getLevel());
|
||||
if (victim->getLevel() > gray_level && (!not_gray_member_with_max_level
|
||||
|| not_gray_member_with_max_level->getLevel() < member->getLevel()))
|
||||
not_gray_member_with_max_level = member;
|
||||
}
|
||||
|
||||
if (member_with_max_level)
|
||||
{
|
||||
xp = !not_gray_member_with_max_level ? 0 : Trinity::XP::Gain(not_gray_member_with_max_level, victim);
|
||||
|
||||
if (!xp)
|
||||
return;
|
||||
|
||||
float group_rate = 1.0f;
|
||||
|
||||
for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player* pGroupGuy = itr->getSource();
|
||||
if (!pGroupGuy)
|
||||
continue;
|
||||
|
||||
if (!pGroupGuy->IsAtGroupRewardDistance(victim))
|
||||
continue; // member (alive or dead) or his corpse at req. distance
|
||||
|
||||
float rate = group_rate * float(pGroupGuy->getLevel()) / sum_level;
|
||||
|
||||
// XP updated only for alive group member
|
||||
if (pGroupGuy->isAlive() && not_gray_member_with_max_level && pGroupGuy->getLevel() <= not_gray_member_with_max_level->getLevel())
|
||||
{
|
||||
uint32 itr_xp = (member_with_max_level == not_gray_member_with_max_level) ? uint32(xp * rate) : uint32((xp * rate / 2) + 1);
|
||||
|
||||
// handle SPELL_AURA_MOD_XP_PCT auras
|
||||
Unit::AuraEffectList const& ModXPPctAuras = plr->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
|
||||
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
|
||||
AddPctN(itr_xp, (*i)->GetAmount());
|
||||
|
||||
pGroupGuy->GiveXP(itr_xp, victim);
|
||||
if (Pet* pet = pGroupGuy->GetPet())
|
||||
pet->GivePetXP(itr_xp / 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else//should be always in a raid group while in any BG, but you never know...
|
||||
{
|
||||
xp = Trinity::XP::Gain(plr, victim);
|
||||
|
||||
if (!xp)
|
||||
return;
|
||||
|
||||
// handle SPELL_AURA_MOD_XP_PCT auras
|
||||
Unit::AuraEffectList const& ModXPPctAuras = plr->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
|
||||
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
|
||||
AddPctN(xp, (*i)->GetAmount());
|
||||
|
||||
plr->GiveXP(xp, victim);
|
||||
|
||||
if (Pet* pet = plr->GetPet())
|
||||
pet->GivePetXP(xp);
|
||||
}
|
||||
if (sWorld->getBoolConfig(CONFIG_BG_XP_FOR_KILL) && killer && victim)
|
||||
killer->RewardPlayerAndGroupAtKill(victim, true);
|
||||
}
|
||||
|
||||
@@ -584,7 +584,7 @@ class Battleground
|
||||
/* virtual score-array - get's used in bg-subclasses */
|
||||
int32 m_TeamScores[BG_TEAMS_COUNT];
|
||||
|
||||
void RewardXPAtKill(Player* plr, Player* victim);
|
||||
void RewardXPAtKill(Player* killer, Player* victim);
|
||||
bool CanAwardArenaPoints() const { return m_LevelMin >= BG_AWARD_ARENA_POINTS_MIN_LEVEL; }
|
||||
|
||||
protected:
|
||||
|
||||
@@ -381,6 +381,229 @@ void TradeData::SetAccepted(bool state, bool crosssend /*= false*/)
|
||||
}
|
||||
}
|
||||
|
||||
// == KillRewarder ====================================================
|
||||
// KillRewarder incapsulates logic of rewarding player upon kill with:
|
||||
// * XP;
|
||||
// * honor;
|
||||
// * reputation;
|
||||
// * kill credit (for quest objectives).
|
||||
// Rewarding is initiated in two cases: when player kills unit in Unit::Kill()
|
||||
// and on battlegrounds in Battleground::RewardXPAtKill().
|
||||
//
|
||||
// Rewarding algorithm is:
|
||||
// 1. Initialize internal variables to default values.
|
||||
// 2. In case when player is in group, initialize variables necessary for group calculations:
|
||||
// 2.1. _count - number of alive group members within reward distance;
|
||||
// 2.2. _sumLevel - sum of levels of alive group members within reward distance;
|
||||
// 2.3. _maxLevel - maximum level of alive group member within reward distance;
|
||||
// 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance,
|
||||
// for whom victim is not gray;
|
||||
// 2.5. _isFullXP - flag identifying that for all group members victim is not gray,
|
||||
// so 100% XP will be rewarded (50% otherwise).
|
||||
// 3. Reward killer (and group, if necessary).
|
||||
// 3.1. If killer is in group, reward group.
|
||||
// 3.1.1. Initialize initial XP amount based on maximum level of group member,
|
||||
// for whom victim is not gray.
|
||||
// 3.1.2. Alter group rate if group is in raid (not for battlegrounds).
|
||||
// 3.1.3. Reward each group member (even dead) within reward distance (see 4. for more details).
|
||||
// 3.2. Reward single killer (not group case).
|
||||
// 3.2.1. Initialize initial XP amount based on killer's level.
|
||||
// 3.2.2. Reward killer (see 4. for more details).
|
||||
// 4. Reward player.
|
||||
// 4.1. Give honor (player must be alive and not on BG).
|
||||
// 4.2. Give XP.
|
||||
// 4.2.1. If player is in group, adjust XP:
|
||||
// * set to 0 if player's level is more than maximum level of not gray member;
|
||||
// * cut XP in half if _isFullXP is false.
|
||||
// 4.2.2. Apply auras modifying rewarded XP.
|
||||
// 4.2.3. Give XP to player.
|
||||
// 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case).
|
||||
// 4.3. Give reputation (player must not be on BG).
|
||||
// 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse).
|
||||
// 5. Credit instance encounter.
|
||||
KillRewarder::KillRewarder(Player* killer, Unit* victim, bool isBattleGround) :
|
||||
// 1. Initialize internal variables to default values.
|
||||
_killer(killer), _victim(victim), _isBattleGround(isBattleGround),
|
||||
_isPvP(victim->isCharmedOwnedByPlayerOrPlayer()), _group(killer->GetGroup()), _groupRate(1.0f),
|
||||
_maxLevel(0), _maxNotGrayMember(NULL), _count(0), _sumLevel(0), _isFullXP(false), _xp(0)
|
||||
{
|
||||
_InitGroupData();
|
||||
}
|
||||
|
||||
inline void KillRewarder::_InitGroupData()
|
||||
{
|
||||
if (_group)
|
||||
{
|
||||
// 2. In case when player is in group, initialize variables necessary for group calculations:
|
||||
for (GroupReference *itr = _group->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
if (Player* member = itr->getSource())
|
||||
if (member->isAlive() && member->IsAtGroupRewardDistance(_victim))
|
||||
{
|
||||
const uint8 lvl = member->getLevel();
|
||||
// 2.1. _count - number of alive group members within reward distance;
|
||||
++_count;
|
||||
// 2.2. _sumLevel - sum of levels of alive group members within reward distance;
|
||||
_sumLevel += lvl;
|
||||
// 2.3. _maxLevel - maximum level of alive group member within reward distance;
|
||||
if (_maxLevel < lvl)
|
||||
_maxLevel = lvl;
|
||||
// 2.4. _maxNotGrayMember - maximum level of alive group member within reward distance,
|
||||
// for whom victim is not gray;
|
||||
uint32 grayLevel = Trinity::XP::GetGrayLevel(lvl);
|
||||
if (_victim->getLevel() > grayLevel && (!_maxNotGrayMember || _maxNotGrayMember->getLevel() < lvl))
|
||||
_maxNotGrayMember = member;
|
||||
}
|
||||
// 2.5. _isFullXP - flag identifying that for all group members victim is not gray,
|
||||
// so 100% XP will be rewarded (50% otherwise).
|
||||
_isFullXP = (_maxLevel == _maxNotGrayMember->getLevel());
|
||||
}
|
||||
else
|
||||
_count = 1;
|
||||
}
|
||||
|
||||
inline void KillRewarder::_InitXP(Player* player)
|
||||
{
|
||||
// Get initial value of XP for kill.
|
||||
// XP is given:
|
||||
// * on battlegrounds;
|
||||
// * otherwise, not in PvP;
|
||||
// * not if killer is on vehicle.
|
||||
if (_isBattleGround || !_isPvP || !_killer->GetVehicle())
|
||||
_xp = Trinity::XP::Gain(player, _victim);
|
||||
}
|
||||
|
||||
inline void KillRewarder::_RewardHonor(Player* player)
|
||||
{
|
||||
// Rewarded player must be alive.
|
||||
if (player->isAlive())
|
||||
player->RewardHonor(_victim, _count, -1, true);
|
||||
}
|
||||
|
||||
inline void KillRewarder::_RewardXP(Player* player, float rate)
|
||||
{
|
||||
uint32 xp(_xp);
|
||||
if (_group)
|
||||
// 4.2.1. If player is in group, adjust XP:
|
||||
// * set to 0 if player's level is more than maximum level of not gray member;
|
||||
// * cut XP in half if _isFullXP is false.
|
||||
if (_maxNotGrayMember && player->isAlive() &&
|
||||
_maxNotGrayMember->getLevel() >= player->getLevel())
|
||||
xp = _isFullXP ?
|
||||
uint32(xp * rate) : // Reward FULL XP if all group members are not gray.
|
||||
uint32(xp * rate / 2) + 1; // Reward only HALF of XP if some of group members are gray.
|
||||
else
|
||||
xp = 0;
|
||||
if (xp)
|
||||
{
|
||||
// 4.2.2. Apply auras modifying rewarded XP (SPELL_AURA_MOD_XP_PCT).
|
||||
Unit::AuraEffectList const& auras = player->GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
|
||||
for (Unit::AuraEffectList::const_iterator i = auras.begin(); i != auras.end(); ++i)
|
||||
AddPctN(xp, (*i)->GetAmount());
|
||||
|
||||
// 4.2.3. Give XP to player.
|
||||
player->GiveXP(xp, _victim, _groupRate);
|
||||
if (Pet* pet = player->GetPet())
|
||||
// 4.2.4. If player has pet, reward pet with XP (100% for single player, 50% for group case).
|
||||
pet->GivePetXP(_group ? xp / 2 : xp);
|
||||
}
|
||||
}
|
||||
|
||||
inline void KillRewarder::_RewardReputation(Player* player, float rate)
|
||||
{
|
||||
// 4.3. Give reputation (player must not be on BG).
|
||||
// Even dead players and corpses are rewarded.
|
||||
player->RewardReputation(_victim, rate);
|
||||
}
|
||||
|
||||
inline void KillRewarder::_RewardKillCredit(Player* player)
|
||||
{
|
||||
// 4.4. Give kill credit (player must not be in group, or he must be alive or without corpse).
|
||||
if (!_group || player->isAlive() || !player->GetCorpse())
|
||||
if (_victim->GetTypeId() == TYPEID_UNIT)
|
||||
player->KilledMonster(_victim->ToCreature()->GetCreatureInfo(), _victim->GetGUID());
|
||||
}
|
||||
|
||||
void KillRewarder::_RewardPlayer(Player* player, bool isDungeon)
|
||||
{
|
||||
// 4. Reward player.
|
||||
if (!_isBattleGround)
|
||||
// 4.1. Give honor (player must be alive and not on BG).
|
||||
_RewardHonor(player);
|
||||
// Give XP only in PvE or in battlegrounds.
|
||||
// Give reputation and kill credit only in PvE.
|
||||
if (!_isPvP || _isBattleGround)
|
||||
{
|
||||
const float rate = _group ?
|
||||
_groupRate * float(player->getLevel()) / _sumLevel : // Group rate depends on summary level.
|
||||
1.0f; // Personal rate is 100%.
|
||||
if (_xp)
|
||||
// 4.2. Give XP.
|
||||
_RewardXP(player, rate);
|
||||
if (!_isBattleGround)
|
||||
{
|
||||
// If killer is in dungeon then all members receive full reputation at kill.
|
||||
_RewardReputation(player, isDungeon ? 1.0f : rate);
|
||||
_RewardKillCredit(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KillRewarder::_RewardGroup()
|
||||
{
|
||||
if (_maxLevel)
|
||||
{
|
||||
if (_maxNotGrayMember)
|
||||
// 3.1.1. Initialize initial XP amount based on maximum level of group member,
|
||||
// for whom victim is not gray.
|
||||
_InitXP(_maxNotGrayMember);
|
||||
// To avoid unnecessary calculations and calls,
|
||||
// proceed only if XP is not ZERO or player is not on battleground
|
||||
// (battleground rewards only XP, that's why).
|
||||
if (!_isBattleGround || _xp)
|
||||
{
|
||||
const bool isDungeon = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsDungeon();
|
||||
if (!_isBattleGround)
|
||||
{
|
||||
// 3.1.2. Alter group rate if group is in raid (not for battlegrounds).
|
||||
const bool isRaid = !_isPvP && sMapStore.LookupEntry(_killer->GetMapId())->IsRaid() && _group->isRaidGroup();
|
||||
_groupRate = Trinity::XP::xp_in_group_rate(_count, isRaid);
|
||||
}
|
||||
|
||||
// 3.1.3. Reward each group member (even dead or corpse) within reward distance.
|
||||
for (GroupReference *itr = _group->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
if (Player* member = itr->getSource())
|
||||
if (member->IsAtGroupRewardDistance(_victim))
|
||||
_RewardPlayer(member, isDungeon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void KillRewarder::Reward()
|
||||
{
|
||||
// 3. Reward killer (and group, if necessary).
|
||||
if (_group)
|
||||
// 3.1. If killer is in group, reward group.
|
||||
_RewardGroup();
|
||||
else
|
||||
{
|
||||
// 3.2. Reward single killer (not group case).
|
||||
// 3.2.1. Initialize initial XP amount based on killer's level.
|
||||
_InitXP(_killer);
|
||||
// To avoid unnecessary calculations and calls,
|
||||
// proceed only if XP is not ZERO or player is not on battleground
|
||||
// (battleground rewards only XP, that's why).
|
||||
if (!_isBattleGround || _xp)
|
||||
// 3.2.2. Reward killer.
|
||||
_RewardPlayer(_killer, false);
|
||||
}
|
||||
|
||||
// 5. Credit instance encounter.
|
||||
if (Creature* victim = _victim->ToCreature())
|
||||
if (victim->IsDungeonBoss())
|
||||
if (InstanceScript* instance = _victim->GetInstanceScript())
|
||||
instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, _victim->GetEntry(), _victim);
|
||||
}
|
||||
|
||||
// == Player ====================================================
|
||||
|
||||
UpdateMask Player::updateVisualBits;
|
||||
@@ -21969,119 +22192,9 @@ bool Player::GetsRecruitAFriendBonus(bool forXP)
|
||||
return recruitAFriend;
|
||||
}
|
||||
|
||||
bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
|
||||
void Player::RewardPlayerAndGroupAtKill(Unit* pVictim, bool isBattleGround)
|
||||
{
|
||||
bool PvP = pVictim->isCharmedOwnedByPlayerOrPlayer();
|
||||
|
||||
// prepare data for near group iteration (PvP and !PvP cases)
|
||||
uint32 xp = 0;
|
||||
bool honored_kill = false;
|
||||
|
||||
if (Group *pGroup = GetGroup())
|
||||
{
|
||||
uint32 count = 0;
|
||||
uint32 sum_level = 0;
|
||||
Player* member_with_max_level = NULL;
|
||||
Player* not_gray_member_with_max_level = NULL;
|
||||
|
||||
pGroup->GetDataForXPAtKill(pVictim,count,sum_level,member_with_max_level,not_gray_member_with_max_level);
|
||||
|
||||
if (member_with_max_level)
|
||||
{
|
||||
// PvP kills doesn't yield experience
|
||||
// also no XP gained if there is no member below gray level
|
||||
xp = (PvP || !not_gray_member_with_max_level || GetVehicle()) ? 0 : Trinity::XP::Gain(not_gray_member_with_max_level, pVictim);
|
||||
|
||||
/// skip in check PvP case (for speed, not used)
|
||||
bool is_raid = PvP ? false : sMapStore.LookupEntry(GetMapId())->IsRaid() && pGroup->isRaidGroup();
|
||||
bool is_dungeon = PvP ? false : sMapStore.LookupEntry(GetMapId())->IsDungeon();
|
||||
float group_rate = Trinity::XP::xp_in_group_rate(count,is_raid);
|
||||
|
||||
for (GroupReference *itr = pGroup->GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player* pGroupGuy = itr->getSource();
|
||||
if (!pGroupGuy)
|
||||
continue;
|
||||
|
||||
if (!pGroupGuy->IsAtGroupRewardDistance(pVictim))
|
||||
continue; // member (alive or dead) or his corpse at req. distance
|
||||
|
||||
// honor can be in PvP and !PvP (racial leader) cases (for alive)
|
||||
if (pGroupGuy->isAlive() && pGroupGuy->RewardHonor(pVictim, count, -1, true) && pGroupGuy == this)
|
||||
honored_kill = true;
|
||||
|
||||
// xp and reputation only in !PvP case
|
||||
if (!PvP)
|
||||
{
|
||||
float rate = group_rate * float(pGroupGuy->getLevel()) / sum_level;
|
||||
|
||||
// if is in dungeon then all receive full reputation at kill
|
||||
// rewarded any alive/dead/near_corpse group member
|
||||
pGroupGuy->RewardReputation(pVictim,is_dungeon ? 1.0f : rate);
|
||||
|
||||
// XP updated only for alive group member
|
||||
if (pGroupGuy->isAlive() && not_gray_member_with_max_level &&
|
||||
pGroupGuy->getLevel() <= not_gray_member_with_max_level->getLevel())
|
||||
{
|
||||
uint32 itr_xp = (member_with_max_level == not_gray_member_with_max_level) ? uint32(xp * rate) : uint32((xp * rate / 2) + 1);
|
||||
|
||||
// handle SPELL_AURA_MOD_XP_PCT auras
|
||||
Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
|
||||
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
|
||||
AddPctN(itr_xp, (*i)->GetAmount());
|
||||
|
||||
pGroupGuy->GiveXP(itr_xp, pVictim, group_rate);
|
||||
if (Pet* pet = pGroupGuy->GetPet())
|
||||
pet->GivePetXP(itr_xp / 2);
|
||||
}
|
||||
|
||||
// quest objectives updated only for alive group member or dead but with not released body
|
||||
if (pGroupGuy->isAlive()|| !pGroupGuy->GetCorpse())
|
||||
{
|
||||
// normal creature (not pet/etc) can be only in !PvP case
|
||||
if (pVictim->GetTypeId() == TYPEID_UNIT)
|
||||
pGroupGuy->KilledMonster(pVictim->ToCreature()->GetCreatureInfo(), pVictim->GetGUID());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else // if (!pGroup)
|
||||
{
|
||||
xp = (PvP || GetVehicle()) ? 0 : Trinity::XP::Gain(this, pVictim);
|
||||
|
||||
// honor can be in PvP and !PvP (racial leader) cases
|
||||
if (RewardHonor(pVictim, 1, -1, true))
|
||||
honored_kill = true;
|
||||
|
||||
// xp and reputation only in !PvP case
|
||||
if (!PvP)
|
||||
{
|
||||
RewardReputation(pVictim,1);
|
||||
|
||||
// handle SPELL_AURA_MOD_XP_PCT auras
|
||||
Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_PCT);
|
||||
for (Unit::AuraEffectList::const_iterator i = ModXPPctAuras.begin(); i != ModXPPctAuras.end(); ++i)
|
||||
AddPctN(xp, (*i)->GetAmount());
|
||||
|
||||
GiveXP(xp, pVictim);
|
||||
|
||||
if (Pet* pet = GetPet())
|
||||
pet->GivePetXP(xp);
|
||||
|
||||
// normal creature (not pet/etc) can be only in !PvP case
|
||||
if (pVictim->GetTypeId() == TYPEID_UNIT)
|
||||
KilledMonster(pVictim->ToCreature()->GetCreatureInfo(), pVictim->GetGUID());
|
||||
}
|
||||
}
|
||||
|
||||
// Credit encounter in instance
|
||||
if (Creature* victim = pVictim->ToCreature())
|
||||
if (victim->IsDungeonBoss())
|
||||
if (InstanceScript* instance = pVictim->GetInstanceScript())
|
||||
instance->UpdateEncounterState(ENCOUNTER_CREDIT_KILL_CREATURE, pVictim->GetEntry(), pVictim);
|
||||
|
||||
return xp || honored_kill;
|
||||
KillRewarder(this, pVictim, isBattleGround).Reward();
|
||||
}
|
||||
|
||||
void Player::RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewardSource)
|
||||
|
||||
@@ -988,6 +988,41 @@ class TradeData
|
||||
uint64 m_items[TRADE_SLOT_COUNT]; // traded itmes from m_player side including non-traded slot
|
||||
};
|
||||
|
||||
class KillRewarder
|
||||
{
|
||||
public:
|
||||
KillRewarder(Player* killer, Unit* victim, bool isBattleGround);
|
||||
|
||||
void Reward();
|
||||
|
||||
private:
|
||||
void _InitXP(Player* player);
|
||||
void _InitGroupData();
|
||||
|
||||
void _RewardHonor(Player* player);
|
||||
void _RewardXP(Player* player, float rate);
|
||||
void _RewardReputation(Player* player, float rate);
|
||||
void _RewardKillCredit(Player* player);
|
||||
void _RewardPlayer(Player* player, bool isDungeon);
|
||||
void _RewardGroup();
|
||||
|
||||
Player* _killer;
|
||||
Unit* _victim;
|
||||
bool _isBattleGround;
|
||||
|
||||
bool _isPvP;
|
||||
|
||||
Group* _group;
|
||||
float _groupRate;
|
||||
uint8 _maxLevel;
|
||||
Player* _maxNotGrayMember;
|
||||
uint32 _count;
|
||||
uint32 _sumLevel;
|
||||
bool _isFullXP;
|
||||
|
||||
uint32 _xp;
|
||||
};
|
||||
|
||||
class Player : public Unit, public GridObject<Player>
|
||||
{
|
||||
friend class WorldSession;
|
||||
@@ -1935,8 +1970,8 @@ class Player : public Unit, public GridObject<Player>
|
||||
|
||||
bool IsAtGroupRewardDistance(WorldObject const* pRewardSource) const;
|
||||
bool IsAtRecruitAFriendDistance(WorldObject const* pOther) const;
|
||||
bool RewardPlayerAndGroupAtKill(Unit* pVictim);
|
||||
void RewardPlayerAndGroupAtEvent(uint32 creature_id,WorldObject* pRewardSource);
|
||||
void RewardPlayerAndGroupAtKill(Unit* pVictim, bool isBattleGround);
|
||||
void RewardPlayerAndGroupAtEvent(uint32 creature_id, WorldObject* pRewardSource);
|
||||
bool isHonorOrXPTarget(Unit* pVictim);
|
||||
|
||||
bool GetsRecruitAFriendBonus(bool forXP);
|
||||
|
||||
@@ -15057,7 +15057,7 @@ void Unit::Kill(Unit *pVictim, bool durabilityLoss)
|
||||
loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold);
|
||||
}
|
||||
|
||||
player->RewardPlayerAndGroupAtKill(pVictim);
|
||||
player->RewardPlayerAndGroupAtKill(pVictim, false);
|
||||
}
|
||||
|
||||
// Do KILL and KILLED procs. KILL proc is called only for the unit who landed the killing blow (and its owner - for pets and totems) regardless of who tapped the victim
|
||||
|
||||
@@ -1161,28 +1161,6 @@ void Group::SetTargetIcon(uint8 id, uint64 whoGuid, uint64 targetGuid)
|
||||
BroadcastPacket(&data, true);
|
||||
}
|
||||
|
||||
void Group::GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_level, Player* & member_with_max_level, Player* & not_gray_member_with_max_level)
|
||||
{
|
||||
for (GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
|
||||
{
|
||||
Player* member = itr->getSource();
|
||||
if (!member || !member->isAlive()) // only for alive
|
||||
continue;
|
||||
|
||||
if (!member->IsAtGroupRewardDistance(victim)) // at req. distance
|
||||
continue;
|
||||
|
||||
++count;
|
||||
sum_level += member->getLevel();
|
||||
if (!member_with_max_level || member_with_max_level->getLevel() < member->getLevel())
|
||||
member_with_max_level = member;
|
||||
|
||||
uint32 gray_level = Trinity::XP::GetGrayLevel(member->getLevel());
|
||||
if (victim->getLevel() > gray_level && (!not_gray_member_with_max_level || not_gray_member_with_max_level->getLevel() < member->getLevel()))
|
||||
not_gray_member_with_max_level = member;
|
||||
}
|
||||
}
|
||||
|
||||
void Group::SendTargetIconList(WorldSession *session)
|
||||
{
|
||||
if (!session)
|
||||
|
||||
@@ -232,7 +232,6 @@ class Group
|
||||
MemberSlotList const& GetMemberSlots() const;
|
||||
GroupReference* GetFirstMember();
|
||||
uint32 GetMembersCount() const;
|
||||
void GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_level, Player* & member_with_max_level, Player* & not_gray_member_with_max_level);
|
||||
uint8 GetMemberGroup(uint64 guid) const;
|
||||
|
||||
void ConvertToLFG();
|
||||
|
||||
Reference in New Issue
Block a user