From bed8794a752aa11c37d794b475bc9aee60055d92 Mon Sep 17 00:00:00 2001 From: VladimirMangos Date: Tue, 18 May 2010 04:39:59 +0400 Subject: [PATCH] [9921] In case player who tap creature in group leave group it must anyway rewarded with group. --- src/game/CharacterHandler.cpp | 5 +- src/game/Group.cpp | 128 ++++++++++++++++++++++------------ src/game/Group.h | 6 +- src/game/Unit.cpp | 2 +- src/shared/revision_nr.h | 2 +- 5 files changed, 88 insertions(+), 55 deletions(-) diff --git a/src/game/CharacterHandler.cpp b/src/game/CharacterHandler.cpp index 7d5edd6cc..8357ede9e 100644 --- a/src/game/CharacterHandler.cpp +++ b/src/game/CharacterHandler.cpp @@ -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); diff --git a/src/game/Group.cpp b/src/game/Group.cpp index c4cff2796..b0909df4f 100644 --- a/src/game/Group.cpp +++ b/src/game/Group.cpp @@ -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,11 +1710,51 @@ 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(); + // honor can be in PvP and !PvP (racial leader) cases (for alive) + if (pGroupGuy->isAlive()) + pGroupGuy->RewardHonor(pVictim,count); + // 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); + + pGroupGuy->GiveXP(itr_xp, pVictim); + 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->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) + { + // normal creature (not pet/etc) can be only in !PvP case + if(pVictim->GetTypeId()==TYPEID_UNIT) + 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) @@ -1707,7 +1765,7 @@ void Group::RewardGroupAtKill(Unit* pVictim) 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); + GetDataForXPAtKill(pVictim,count,sum_level,member_with_max_level,not_gray_member_with_max_level,player_tap); if(member_with_max_level) { @@ -1725,41 +1783,21 @@ void Group::RewardGroupAtKill(Unit* pVictim) 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 - // honor can be in PvP and !PvP (racial leader) cases (for alive) - if (pGroupGuy->isAlive()) - pGroupGuy->RewardHonor(pVictim,count); + RewardGroupAtKill_helper(pGroupGuy, pVictim, count, PvP, group_rate, sum_level, is_dungeon, not_gray_member_with_max_level, member_with_max_level, xp); + } - // 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); - - pGroupGuy->GiveXP(itr_xp, pVictim); - 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->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_GHOST)) - { - // normal creature (not pet/etc) can be only in !PvP case - if(pVictim->GetTypeId()==TYPEID_UNIT) - pGroupGuy->KilledMonster(((Creature*)pVictim)->GetCreatureInfo(), pVictim->GetObjectGuid()); - } - } + 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); } } } diff --git a/src/game/Group.h b/src/game/Group.h index 3b0204994..05848cacf 100644 --- a/src/game/Group.h +++ b/src/game/Group.h @@ -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 ***/ diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp index 37249b285..9c8ed0b9d 100644 --- a/src/game/Unit.cpp +++ b/src/game/Unit.cpp @@ -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); } diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 571731cbd..8c74a8f6e 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "9920" + #define REVISION_NR "9921" #endif // __REVISION_NR_H__