mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 13:37:05 +00:00
[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:
parent
96d50bf55a
commit
696a4b6db0
13 changed files with 223 additions and 135 deletions
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -531,11 +531,16 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
|||
Loot loot;
|
||||
bool lootForPickPocketed;
|
||||
bool lootForBody;
|
||||
Player *GetLootRecipient() const;
|
||||
bool hasLootRecipient() const { return m_lootRecipient!=0; }
|
||||
|
||||
void SetLootRecipient (Unit* unit);
|
||||
ObjectGuid GetLootRecipientGuid() const { return m_lootRecipientGuid; }
|
||||
uint32 GetLootGroupRecipientId() const { return m_lootGroupRecipientId; }
|
||||
Player* GetLootRecipient() const; // use group cases as prefered
|
||||
Group* GetGroupLootRecipient() const;
|
||||
bool HasLootRecipient() const { return m_lootGroupRecipientId || !m_lootRecipientGuid.IsEmpty(); }
|
||||
bool IsGroupLootRecipient() const { return m_lootGroupRecipientId; }
|
||||
void SetLootRecipient(Unit* unit);
|
||||
void AllLootRemovedFromCorpse();
|
||||
Player* GetOriginalLootRecipient() const; // ignore group changes/etc, not for looting
|
||||
|
||||
SpellEntry const *reachWithSpellAttack(Unit *pVictim);
|
||||
SpellEntry const *reachWithSpellCure(Unit *pVictim);
|
||||
|
|
@ -641,7 +646,8 @@ class MANGOS_DLL_SPEC Creature : public Unit
|
|||
static float _GetDamageMod(int32 Rank);
|
||||
|
||||
uint32 m_lootMoney;
|
||||
uint64 m_lootRecipient;
|
||||
ObjectGuid m_lootRecipientGuid; // player who will have rights for looting if m_lootGroupRecipient==0 or group disbanded
|
||||
uint32 m_lootGroupRecipientId; // group who will have rights for looting if set and exist
|
||||
|
||||
/// Timers
|
||||
uint32 m_deathTimer; // (msecs)timer for death or corpse disappearance
|
||||
|
|
|
|||
|
|
@ -698,7 +698,7 @@ void CreatureEventAI::ProcessAction(CreatureEventAI_Action const& action, uint32
|
|||
break;
|
||||
}
|
||||
case ACTION_T_KILLED_MONSTER:
|
||||
//first attempt player who tapped creature
|
||||
//first attempt player/group who tapped creature
|
||||
if (Player* pPlayer = m_creature->GetLootRecipient())
|
||||
pPlayer->RewardPlayerAndGroupAtEvent(action.killed_monster.creatureId, m_creature);
|
||||
else
|
||||
|
|
|
|||
|
|
@ -1691,3 +1691,75 @@ void Group::_homebindIfInstance(Player *player)
|
|||
player->m_InstanceValid = false;
|
||||
}
|
||||
}
|
||||
|
||||
void Group::RewardGroupAtKill(Unit* pVictim)
|
||||
{
|
||||
// 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);
|
||||
|
||||
// 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -323,6 +323,8 @@ class MANGOS_DLL_SPEC Group
|
|||
void BroadcastReadyCheck(WorldPacket *packet);
|
||||
void OfflineReadyCheck();
|
||||
|
||||
void RewardGroupAtKill(Unit* pVictim);
|
||||
|
||||
/*********************************************************/
|
||||
/*** LOOT SYSTEM ***/
|
||||
/*********************************************************/
|
||||
|
|
|
|||
|
|
@ -436,10 +436,9 @@ void WorldSession::DoLootRelease(ObjectGuid lguid)
|
|||
loot = &pCreature->loot;
|
||||
|
||||
// update next looter
|
||||
if(Player *recipient = pCreature->GetLootRecipient())
|
||||
if(Group* group = recipient->GetGroup())
|
||||
if (group->GetLooterGuid() == player->GetGUID())
|
||||
group->UpdateLooterGuid(pCreature);
|
||||
if(Group* group = pCreature->GetGroupLootRecipient())
|
||||
if (group->GetLooterGuid() == player->GetGUID())
|
||||
group->UpdateLooterGuid(pCreature);
|
||||
|
||||
if (loot->isLooted())
|
||||
{
|
||||
|
|
|
|||
|
|
@ -130,6 +130,7 @@ class MANGOS_DLL_SPEC ObjectGuid
|
|||
PackedGuidReader ReadAsPacked() { return PackedGuidReader(*this); }
|
||||
|
||||
void Set(uint64 const& guid) { m_guid = guid; }
|
||||
void Clear() { m_guid = 0; }
|
||||
|
||||
// Possible removed in future for more strict control type conversions
|
||||
void operator= (uint64 const& guid) { m_guid = guid; }
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1904,7 +1904,7 @@ class MANGOS_DLL_SPEC Player : public Unit
|
|||
void InitDisplayIds();
|
||||
|
||||
bool IsAtGroupRewardDistance(WorldObject const* pRewardSource) const;
|
||||
bool RewardPlayerAndGroupAtKill(Unit* pVictim);
|
||||
bool RewardSinglePlayerAtKill(Unit* pVictim);
|
||||
void RewardPlayerAndGroupAtEvent(uint32 creature_id,WorldObject* pRewardSource);
|
||||
bool isHonorOrXPTarget(Unit* pVictim) const;
|
||||
|
||||
|
|
|
|||
|
|
@ -5675,7 +5675,7 @@ void Spell::EffectScriptEffect(SpellEffectIndex eff_idx)
|
|||
if (m_caster->GetTypeId() != TYPEID_UNIT)
|
||||
return;
|
||||
|
||||
Player* pPlayer = ((Creature*)m_caster)->GetLootRecipient();
|
||||
Player* pPlayer = ((Creature*)m_caster)->GetOriginalLootRecipient();
|
||||
|
||||
if (!pPlayer)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -658,7 +658,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||
if (pVictim->GetTypeId() == TYPEID_PLAYER)
|
||||
((Player*)pVictim)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HIGHEST_HIT_RECEIVED, damage);
|
||||
|
||||
if (pVictim->GetTypeId() == TYPEID_UNIT && !((Creature*)pVictim)->isPet() && !((Creature*)pVictim)->hasLootRecipient())
|
||||
if (pVictim->GetTypeId() == TYPEID_UNIT && !((Creature*)pVictim)->isPet() && !((Creature*)pVictim)->HasLootRecipient())
|
||||
((Creature*)pVictim)->SetLootRecipient(this);
|
||||
|
||||
if (health <= damage)
|
||||
|
|
@ -666,35 +666,50 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||
DEBUG_LOG("DealDamage: victim just died");
|
||||
|
||||
// find player: owner of controlled `this` or `this` itself maybe
|
||||
Player *player = GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
// for loot will be sued only if group_tap==NULL
|
||||
Player *player_tap = GetCharmerOrOwnerPlayerOrPlayerItself();
|
||||
Group *group_tap = NULL;
|
||||
|
||||
// find owner of pVictim, used for creature cases, AI calls
|
||||
Unit* pOwner = pVictim->GetCharmerOrOwner();
|
||||
|
||||
if(pVictim->GetTypeId() == TYPEID_UNIT && ((Creature*)pVictim)->GetLootRecipient())
|
||||
player = ((Creature*)pVictim)->GetLootRecipient();
|
||||
if (pVictim->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
group_tap = ((Creature*)pVictim)->GetGroupLootRecipient();
|
||||
|
||||
if (Player* recipient = ((Creature*)pVictim)->GetOriginalLootRecipient())
|
||||
player_tap = recipient;
|
||||
}
|
||||
|
||||
if (pVictim->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
((Player*)pVictim)->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_TOTAL_DAMAGE_RECEIVED, health);
|
||||
if (player)
|
||||
player->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL,1,0,pVictim);
|
||||
if (player_tap)
|
||||
player_tap->UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_SPECIAL_PVP_KILL,1,0,pVictim);
|
||||
}
|
||||
|
||||
// call kill spell proc event (before real die and combat stop to triggering auras removed at death/combat stop)
|
||||
if(player_tap && player_tap != pVictim)
|
||||
{
|
||||
player_tap->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
|
||||
|
||||
WorldPacket data(SMSG_PARTYKILLLOG, (8+8)); //send event PARTY_KILL
|
||||
data << player_tap->GetObjectGuid(); //player with killing blow
|
||||
data << pVictim->GetObjectGuid(); //victim
|
||||
|
||||
if (group_tap)
|
||||
group_tap->BroadcastPacket(&data, false, group_tap->GetMemberGroup(player_tap->GetGUID()),player_tap->GetGUID());
|
||||
|
||||
player_tap->SendDirectMessage(&data);
|
||||
}
|
||||
|
||||
// Reward player, his pets, and group/raid members
|
||||
// call kill spell proc event (before real die and combat stop to triggering auras removed at death/combat stop)
|
||||
if(player && player!=pVictim)
|
||||
if (player_tap != pVictim)
|
||||
{
|
||||
player->RewardPlayerAndGroupAtKill(pVictim);
|
||||
player->ProcDamageAndSpell(pVictim, PROC_FLAG_KILL, PROC_FLAG_KILLED, PROC_EX_NONE, 0);
|
||||
|
||||
WorldPacket data(SMSG_PARTYKILLLOG, (8+8)); //send event PARTY_KILL
|
||||
data << uint64(player->GetGUID()); //player with killing blow
|
||||
data << uint64(pVictim->GetGUID()); //victim
|
||||
if (Group *group = player->GetGroup())
|
||||
group->BroadcastPacket(&data, group->GetMemberGroup(player->GetGUID()));
|
||||
else
|
||||
player->SendDirectMessage(&data);
|
||||
if (group_tap)
|
||||
group_tap->RewardGroupAtKill(pVictim);
|
||||
else if (player_tap)
|
||||
player_tap->RewardSinglePlayerAtKill(pVictim);
|
||||
}
|
||||
|
||||
DEBUG_LOG("DealDamageAttackStop");
|
||||
|
|
@ -749,7 +764,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||
// remember victim PvP death for corpse type and corpse reclaim delay
|
||||
// at original death (not at SpiritOfRedemtionTalent timeout)
|
||||
if( pVictim->GetTypeId()==TYPEID_PLAYER && !damageFromSpiritOfRedemtionTalent )
|
||||
((Player*)pVictim)->SetPvPDeath(player!=NULL);
|
||||
((Player*)pVictim)->SetPvPDeath(player_tap != NULL);
|
||||
|
||||
// Call KilledUnit for creatures
|
||||
if (GetTypeId() == TYPEID_UNIT && ((Creature*)this)->AI())
|
||||
|
|
@ -769,7 +784,7 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||
if (pVictim->GetTypeId() == TYPEID_PLAYER)
|
||||
{
|
||||
// only if not player and not controlled by player pet. And not at BG
|
||||
if (durabilityLoss && !player && !((Player*)pVictim)->InBattleGround())
|
||||
if (durabilityLoss && !player_tap && !((Player*)pVictim)->InBattleGround())
|
||||
{
|
||||
DEBUG_LOG("We are dead, loosing 10 percents durability");
|
||||
((Player*)pVictim)->DurabilityLossAll(0.10f,false);
|
||||
|
|
@ -855,14 +870,14 @@ uint32 Unit::DealDamage(Unit *pVictim, uint32 damage, CleanDamage const* cleanDa
|
|||
{
|
||||
Player *killed = ((Player*)pVictim);
|
||||
if(BattleGround *bg = killed->GetBattleGround())
|
||||
if(player)
|
||||
bg->HandleKillPlayer(killed, player);
|
||||
if(player_tap)
|
||||
bg->HandleKillPlayer(killed, player_tap);
|
||||
}
|
||||
else if(pVictim->GetTypeId() == TYPEID_UNIT)
|
||||
{
|
||||
if (player)
|
||||
if (BattleGround *bg = player->GetBattleGround())
|
||||
bg->HandleKillUnit((Creature*)pVictim, player);
|
||||
if (player_tap)
|
||||
if (BattleGround *bg = player_tap->GetBattleGround())
|
||||
bg->HandleKillUnit((Creature*)pVictim, player_tap);
|
||||
}
|
||||
}
|
||||
else // if (health <= damage)
|
||||
|
|
|
|||
|
|
@ -344,7 +344,16 @@ bool ChatHandler::HandleDebugGetLootRecipientCommand(const char* /*args*/)
|
|||
if (!target)
|
||||
return false;
|
||||
|
||||
PSendSysMessage("loot recipient: %s", target->hasLootRecipient()?(target->GetLootRecipient()?target->GetLootRecipient()->GetName():"offline"):"no loot recipient");
|
||||
if (!target->HasLootRecipient())
|
||||
SendSysMessage("loot recipient: no loot recipient");
|
||||
else if(Player* recipient = target->GetLootRecipient())
|
||||
PSendSysMessage("loot recipient: %s with raw data %s from group %u",
|
||||
recipient->GetObjectGuid().GetString().c_str(),
|
||||
target->GetLootRecipientGuid().GetString().c_str(),
|
||||
target->GetLootGroupRecipientId());
|
||||
else
|
||||
SendSysMessage("loot recipient: offline ");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "9917"
|
||||
#define REVISION_NR "9918"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue