[9921] In case player who tap creature in group leave group it must anyway rewarded with group.

This commit is contained in:
VladimirMangos 2010-05-18 04:39:59 +04:00
parent e5dc7a098c
commit bed8794a75
5 changed files with 88 additions and 55 deletions

View file

@ -720,11 +720,8 @@ void WorldSession::HandlePlayerLogin(LoginQueryHolder *holder)
pCurrChar->SetInGameTime( getMSTime() );
// announce group about member online (must be after add to player list to receive announce to self)
if(Group *group = pCurrChar->GetGroup())
{
//pCurrChar->groupInfo.group->SendInit(this); // useless
if (Group *group = pCurrChar->GetGroup())
group->SendUpdate();
}
// friend status
sSocialMgr.SendFriendStatus(pCurrChar, FRIEND_ONLINE, pCurrChar->GetGUIDLow(), true);

View file

@ -888,26 +888,44 @@ 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)
static void GetDataForXPAtKill_helper(Player* player, Unit const* victim, uint32& sum_level, Player* & member_with_max_level, Player* & not_gray_member_with_max_level)
{
sum_level += player->getLevel();
if(!member_with_max_level || member_with_max_level->getLevel() < player->getLevel())
member_with_max_level = player;
uint32 gray_level = MaNGOS::XP::GetGrayLevel(player->getLevel());
if( victim->getLevel() > gray_level && (!not_gray_member_with_max_level
|| not_gray_member_with_max_level->getLevel() < player->getLevel()))
not_gray_member_with_max_level = player;
}
void Group::GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_level, Player* & member_with_max_level, Player* & not_gray_member_with_max_level, Player* additional)
{
for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* member = itr->getSource();
if(!member || !member->isAlive()) // only for alive
if (!member || !member->isAlive()) // only for alive
continue;
if(!member->IsAtGroupRewardDistance(victim)) // at req. distance
// will proccesed later
if (member = additional)
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;
GetDataForXPAtKill_helper(member,victim,sum_level,member_with_max_level,not_gray_member_with_max_level);
}
uint32 gray_level = MaNGOS::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 (additional)
{
if (additional->IsAtGroupRewardDistance(victim)) // at req. distance
{
++count;
GetDataForXPAtKill_helper(additional,victim,sum_level,member_with_max_level,not_gray_member_with_max_level);
}
}
}
@ -1692,42 +1710,8 @@ void Group::_homebindIfInstance(Player *player)
}
}
void Group::RewardGroupAtKill(Unit* pVictim)
static void RewardGroupAtKill_helper(Player* pGroupGuy, Unit* pVictim, uint32 count, bool PvP, float group_rate, uint32 sum_level, bool is_dungeon, Player* not_gray_member_with_max_level, Player* member_with_max_level, uint32 xp )
{
// for creature case use tapped group (for avoid use group if not set and use if player switch group after tap
//Group* pGroup = pVictim->GetTypeId() == TYPEID_UNIT ? ((Creature*)pVictim)->GetGroupLootRecipient() : GetGroup();
bool PvP = pVictim->isCharmedOwnedByPlayerOrPlayer();
// prepare data for near group iteration (PvP and !PvP cases)
uint32 xp = 0;
uint32 count = 0;
uint32 sum_level = 0;
Player* member_with_max_level = NULL;
Player* not_gray_member_with_max_level = NULL;
GetDataForXPAtKill(pVictim,count,sum_level,member_with_max_level,not_gray_member_with_max_level);
if(member_with_max_level)
{
/// not get Xp in PvP or no not gray players in group
xp = (PvP || !not_gray_member_with_max_level) ? 0 : MaNGOS::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(pVictim->GetMapId())->IsRaid() && isRaidGroup();
bool is_dungeon = PvP ? false : sMapStore.LookupEntry(pVictim->GetMapId())->IsDungeon();
float group_rate = MaNGOS::XP::xp_in_group_rate(count,is_raid);
for(GroupReference *itr = 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);
@ -1760,6 +1744,60 @@ void Group::RewardGroupAtKill(Unit* pVictim)
pGroupGuy->KilledMonster(((Creature*)pVictim)->GetCreatureInfo(), pVictim->GetObjectGuid());
}
}
}
/** Provide rewards to group members at unit kill
*
* @param pVictim Killed unit
* @param player_tap Player who tap unit if online, it can be group member or can be not if leaved after tap but before kill target
*
* Rewards received by group members and player_tap
*/
void Group::RewardGroupAtKill(Unit* pVictim, Player* player_tap)
{
bool PvP = pVictim->isCharmedOwnedByPlayerOrPlayer();
// prepare data for near group iteration (PvP and !PvP cases)
uint32 xp = 0;
uint32 count = 0;
uint32 sum_level = 0;
Player* member_with_max_level = NULL;
Player* not_gray_member_with_max_level = NULL;
GetDataForXPAtKill(pVictim,count,sum_level,member_with_max_level,not_gray_member_with_max_level,player_tap);
if(member_with_max_level)
{
/// not get Xp in PvP or no not gray players in group
xp = (PvP || !not_gray_member_with_max_level) ? 0 : MaNGOS::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(pVictim->GetMapId())->IsRaid() && isRaidGroup();
bool is_dungeon = PvP ? false : sMapStore.LookupEntry(pVictim->GetMapId())->IsDungeon();
float group_rate = MaNGOS::XP::xp_in_group_rate(count,is_raid);
for(GroupReference *itr = GetFirstMember(); itr != NULL; itr = itr->next())
{
Player* pGroupGuy = itr->getSource();
if(!pGroupGuy)
continue;
// will proccessed later
if(pGroupGuy==player_tap)
continue;
if(!pGroupGuy->IsAtGroupRewardDistance(pVictim))
continue; // member (alive or dead) or his corpse at req. distance
RewardGroupAtKill_helper(pGroupGuy, pVictim, count, PvP, group_rate, sum_level, is_dungeon, not_gray_member_with_max_level, member_with_max_level, xp);
}
if(player_tap)
{
// member (alive or dead) or his corpse at req. distance
if(player_tap->IsAtGroupRewardDistance(pVictim))
RewardGroupAtKill_helper(player_tap, pVictim, count, PvP, group_rate, sum_level, is_dungeon, not_gray_member_with_max_level, member_with_max_level, xp);
}
}
}

View file

@ -259,7 +259,7 @@ class MANGOS_DLL_SPEC Group
MemberSlotList const& GetMemberSlots() const { return m_memberSlots; }
GroupReference* GetFirstMember() { return m_memberMgr.getFirst(); }
uint32 GetMembersCount() const { return m_memberSlots.size(); }
void GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_level, Player* & member_with_max_level, Player* & not_gray_member_with_max_level);
void GetDataForXPAtKill(Unit const* victim, uint32& count,uint32& sum_level, Player* & member_with_max_level, Player* & not_gray_member_with_max_level, Player* additional = NULL);
uint8 GetMemberGroup(uint64 guid) const
{
member_citerator mslot = _getMemberCSlot(guid);
@ -313,8 +313,6 @@ class MANGOS_DLL_SPEC Group
bool InCombatToInstance(uint32 instanceId);
void ResetInstances(uint8 method, bool isRaid, Player* SendMsgTo);
// -no description-
//void SendInit(WorldSession *session);
void SendTargetIconList(WorldSession *session);
void SendUpdate();
void UpdatePlayerOutOfRange(Player* pPlayer);
@ -323,7 +321,7 @@ class MANGOS_DLL_SPEC Group
void BroadcastReadyCheck(WorldPacket *packet);
void OfflineReadyCheck();
void RewardGroupAtKill(Unit* pVictim);
void RewardGroupAtKill(Unit* pVictim, Player* player_tap);
/*********************************************************/
/*** LOOT SYSTEM ***/

View file

@ -714,7 +714,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
if (player_tap != pVictim)
{
if (group_tap)
group_tap->RewardGroupAtKill(pVictim);
group_tap->RewardGroupAtKill(pVictim, player_tap);
else if (player_tap)
player_tap->RewardSinglePlayerAtKill(pVictim);
}

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9920"
#define REVISION_NR "9921"
#endif // __REVISION_NR_H__