[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

@ -111,7 +111,7 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
Creature::Creature(CreatureSubtype subtype) :
Unit(), i_AI(NULL),
lootForPickPocketed(false), lootForBody(false), m_groupLootTimer(0), m_groupLootId(0),
m_lootMoney(0), m_lootRecipient(0),
m_lootMoney(0), m_lootGroupRecipientId(0),
m_deathTimer(0), m_respawnTime(0), m_respawnDelay(25), m_corpseDelay(60), m_respawnradius(5.0f),
m_subtype(subtype), m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0),
m_AlreadyCallAssistance(false), m_AlreadySearchedAssistance(false),
@ -810,13 +810,59 @@ void Creature::AI_SendMoveToPacket(float x, float y, float z, uint32 time, Splin
SendMonsterMove(x, y, z, type, flags, time);
}
Player *Creature::GetLootRecipient() const
/**
* Return original player who tap creature, it can be different from player/group allowed to loot so not use it for loot code
*/
Player* Creature::GetOriginalLootRecipient() const
{
if (!m_lootRecipient)
return NULL;
else return ObjectAccessor::FindPlayer(m_lootRecipient);
return !m_lootRecipientGuid.IsEmpty() ? ObjectAccessor::FindPlayer(m_lootRecipientGuid) : NULL;
}
/**
* Return group if player tap creature as group member, independent is player after leave group or stil be group member
*/
Group* Creature::GetGroupLootRecipient() const
{
// original recipient group if set and not disbanded
return m_lootGroupRecipientId ? sObjectMgr.GetGroupById(m_lootGroupRecipientId) : NULL;
}
/**
* Return player who can loot tapped creature (member of group or single player)
*
* In case when original player tap creature as group member then group tap prefered.
* This is for example important if player after tap leave group.
* If group not exist or disbanded or player tap creature not as group member return player
*/
Player* Creature::GetLootRecipient() const
{
// original recipient group if set and not disbanded
Group* group = GetGroupLootRecipient();
// original recipient player if online
Player* player = GetOriginalLootRecipient();
// if group not set or disbanded return original recipient player if any
if (!group)
return player;
// group case
// return player if it still be in original recipient group
if (player && player->GetGroup() == group)
return player;
// find any in group
for(GroupReference *itr = group->GetFirstMember(); itr != NULL; itr = itr->next())
if (Player *p = itr->getSource())
return p;
return NULL;
}
/**
* Set player and group (if player group member) who tap creature
*/
void Creature::SetLootRecipient(Unit *unit)
{
// set the player whose group should receive the right
@ -825,7 +871,8 @@ void Creature::SetLootRecipient(Unit *unit)
if (!unit)
{
m_lootRecipient = 0;
m_lootRecipientGuid.Clear();
m_lootGroupRecipientId = 0;
RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED);
return;
}
@ -834,7 +881,13 @@ void Creature::SetLootRecipient(Unit *unit)
if(!player) // normal creature, no player involved
return;
m_lootRecipient = player->GetGUID();
// set player for non group case or if group will disbanded
m_lootRecipientGuid = player->GetObjectGuid();
// set group for group existed case including if player will leave group at loot time
if (Group* group = player->GetGroup())
m_lootGroupRecipientId = group->GetId();
SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED);
}