[9918] Fixed player's tapped creature loot access by group in diff cases

* If player tap creature in group and leave then group will have access to creature loot if not disbanded
* If player tap creature and after join to group then creature loot will accesable only by player
* Also RewardPlayerAndGroupAtKill divided to simgle player and group reward versions used for group tap
  and single player tap cases.
This commit is contained in:
VladimirMangos 2010-05-17 08:58:54 +04:00
parent 96d50bf55a
commit 696a4b6db0
13 changed files with 223 additions and 135 deletions

View file

@ -7861,7 +7861,7 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
loot->generateMoneyLoot(creature->GetCreatureInfo()->mingold,creature->GetCreatureInfo()->maxgold);
if (Group* group = recipient->GetGroup())
if (Group* group = creature->GetGroupLootRecipient())
{
group->UpdateLooterGuid(creature,true);
@ -7892,9 +7892,9 @@ void Player::SendLoot(ObjectGuid guid, LootType loot_type)
// set group rights only for loot_type != LOOT_SKINNING
else
{
if(Group* group = GetGroup())
if(Group* group = creature->GetGroupLootRecipient())
{
if (group == recipient->GetGroup())
if (group == GetGroup())
{
if (group->GetLootMethod() == FREE_FOR_ALL)
permission = ALL_PERMISSION;
@ -15452,18 +15452,20 @@ bool Player::isAllowedToLoot(Creature* creature)
{
if (recipient == this)
return true;
if( Group* otherGroup = recipient->GetGroup())
if (Group* otherGroup = recipient->GetGroup())
{
Group* thisGroup = GetGroup();
if(!thisGroup)
if (!thisGroup)
return false;
return thisGroup == otherGroup;
}
return false;
}
else
// prevent other players from looting if the recipient got disconnected
return !creature->hasLootRecipient();
return !creature->HasLootRecipient();
}
void Player::_LoadActions(QueryResult *result)
@ -20099,99 +20101,28 @@ bool Player::isHonorOrXPTarget(Unit* pVictim) const
return true;
}
bool Player::RewardPlayerAndGroupAtKill(Unit* pVictim)
bool Player::RewardSinglePlayerAtKill(Unit* pVictim)
{
bool PvP = pVictim->isCharmedOwnedByPlayerOrPlayer();
uint32 xp = PvP ? 0 : MaNGOS::XP::Gain(this, pVictim);
// prepare data for near group iteration (PvP and !PvP cases)
uint32 xp = 0;
bool honored_kill = false;
// honor can be in PvP and !PvP (racial leader) cases
bool honored_kill = RewardHonor(pVictim,1);
if(Group *pGroup = GetGroup())
// xp and reputation only in !PvP case
if(!PvP)
{
uint32 count = 0;
uint32 sum_level = 0;
Player* member_with_max_level = NULL;
Player* not_gray_member_with_max_level = NULL;
RewardReputation(pVictim,1);
GiveXP(xp, pVictim);
pGroup->GetDataForXPAtKill(pVictim,count,sum_level,member_with_max_level,not_gray_member_with_max_level);
if(Pet* pet = GetPet())
pet->GivePetXP(xp);
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(GetMapId())->IsRaid() && pGroup->isRaidGroup();
bool is_dungeon = PvP ? false : sMapStore.LookupEntry(GetMapId())->IsDungeon();
float group_rate = MaNGOS::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) && 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);
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());
}
}
}
}
// normal creature (not pet/etc) can be only in !PvP case
if(pVictim->GetTypeId()==TYPEID_UNIT)
KilledMonster(((Creature*)pVictim)->GetCreatureInfo(), pVictim->GetObjectGuid());
}
else // if (!pGroup)
{
xp = PvP ? 0 : MaNGOS::XP::Gain(this, pVictim);
// honor can be in PvP and !PvP (racial leader) cases
if(RewardHonor(pVictim,1))
honored_kill = true;
// xp and reputation only in !PvP case
if(!PvP)
{
RewardReputation(pVictim,1);
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(((Creature*)pVictim)->GetCreatureInfo(), pVictim->GetObjectGuid());
}
}
return xp || honored_kill;
}