aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Creature.cpp24
-rw-r--r--src/game/Creature.h5
-rw-r--r--src/game/Object.cpp48
-rw-r--r--src/game/Player.cpp6
-rw-r--r--src/game/Player.h2
-rw-r--r--src/game/SpellAuraEffects.cpp2
6 files changed, 62 insertions, 25 deletions
diff --git a/src/game/Creature.cpp b/src/game/Creature.cpp
index 9b4332a579f..8404702f748 100644
--- a/src/game/Creature.cpp
+++ b/src/game/Creature.cpp
@@ -973,8 +973,7 @@ void Creature::SetLootRecipient(Unit *unit)
if (!unit)
{
m_lootRecipient = 0;
- RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
- RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED);
+ RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE|UNIT_DYNFLAG_TAPPED);
return;
}
@@ -986,6 +985,27 @@ void Creature::SetLootRecipient(Unit *unit)
SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_TAPPED);
}
+// return true if this creature is tapped by the player or by a member of his group.
+bool Creature::isTappedBy(Player *player) const
+{
+ if (player->GetGUID() == m_lootRecipient)
+ return true;
+
+ Player* recipient = GetLootRecipient();
+ if (!recipient)
+ return false; // recipient exist but is offline. can't check any further.
+
+ Group* recipientGroup = recipient->GetGroup();
+ if (!recipientGroup)
+ return (player == recipient);
+
+ Group* playerGroup = player->GetGroup();
+ if (!playerGroup || playerGroup != recipientGroup)
+ return false;
+
+ return true;
+}
+
void Creature::SaveToDB()
{
// this should only be used when the creature has already been loaded
diff --git a/src/game/Creature.h b/src/game/Creature.h
index e0f66eb1963..cef677edc29 100644
--- a/src/game/Creature.h
+++ b/src/game/Creature.h
@@ -528,7 +528,8 @@ class Creature : public Unit, public GridObject<Creature>
bool lootForPickPocketed;
bool lootForBody;
Player *GetLootRecipient() const;
- bool hasLootRecipient() const { return m_lootRecipient!=0; }
+ bool hasLootRecipient() const { return m_lootRecipient != 0; }
+ bool isTappedBy(Player *player) const; // return true if the creature is tapped by the player or a member of his party.
void SetLootRecipient (Unit* unit);
void AllLootRemovedFromCorpse();
@@ -636,7 +637,7 @@ class Creature : public Unit, public GridObject<Creature>
void SetDisableReputationGain(bool disable) { DisableReputationGain = disable; }
bool IsReputationGainDisabled() { return DisableReputationGain; }
- bool IsDamageEnoughForLootingAndReward() { return m_PlayerDamageReq == 0; }
+ bool IsDamageEnoughForLootingAndReward() const { return m_PlayerDamageReq == 0; }
void LowerPlayerDamageReq(uint32 unDamage)
{
if(m_PlayerDamageReq)
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 3e0bbfffb27..a5279e6a581 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -528,7 +528,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
{
if( updateMask->GetBit( index ) )
{
- if( index == UNIT_NPC_FLAGS )
+ if (index == UNIT_NPC_FLAGS)
{
// remove custom flag before sending
uint32 appendValue = m_uint32Values[ index ] & ~(UNIT_NPC_FLAG_GUARD + UNIT_NPC_FLAG_OUTDOORPVP);
@@ -553,7 +553,7 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
*data << ((Unit*)this)->BuildAuraStateUpdateForTarget(target);
}
// FIXME: Some values at server stored in float format but must be sent to client in uint32 format
- else if(index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
+ else if (index >= UNIT_FIELD_BASEATTACKTIME && index <= UNIT_FIELD_RANGEDATTACKTIME)
{
// convert from float to uint32 and send
*data << uint32(m_floatValues[ index ] < 0 ? 0 : m_floatValues[ index ]);
@@ -604,17 +604,35 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
*data << m_uint32Values[ index ];
}
// hide lootable animation for unallowed players
- else if(index == UNIT_DYNAMIC_FLAGS)
+ else if (index == UNIT_DYNAMIC_FLAGS)
{
- if(GetTypeId() == TYPEID_UNIT)
+ uint32 dynamicFlags = m_uint32Values[index];
+
+ if (const Creature* creature = ToCreature())
{
- if(!target->isAllowedToLoot(const_cast<Creature*>(this->ToCreature())))
- *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_LOOTABLE);
+ if (creature->hasLootRecipient())
+ {
+ if (creature->isTappedBy(target))
+ {
+ dynamicFlags |= (UNIT_DYNFLAG_TAPPED|UNIT_DYNFLAG_TAPPED_BY_PLAYER);
+ }
+ else
+ {
+ dynamicFlags |= UNIT_DYNFLAG_TAPPED;
+ dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER;
+ }
+ }
else
- *data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_TAPPED);
+ {
+ dynamicFlags &= ~UNIT_DYNFLAG_TAPPED;
+ dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER;
+ }
+
+ if (!target->isAllowedToLoot(ToCreature()))
+ dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE;
}
- else
- *data << m_uint32Values[ index ];
+
+ *data << dynamicFlags;
}
// FG: pretend that OTHER players in own group are friendly ("blue")
else if(index == UNIT_FIELD_BYTES_2 || index == UNIT_FIELD_FACTIONTEMPLATE)
@@ -2246,15 +2264,13 @@ void WorldObject::DestroyForNearbyPlayers()
if(!IsInWorld())
return;
- std::list<Unit*> targets;
- Trinity::AnyUnitInObjectRangeCheck check(this, GetMap()->GetVisibilityDistance());
- Trinity::UnitListSearcher<Trinity::AnyUnitInObjectRangeCheck> searcher(this, targets, check);
+ std::list<Player*> targets;
+ Trinity::AnyPlayerInObjectRangeCheck check(this, GetMap()->GetVisibilityDistance());
+ Trinity::PlayerListSearcher<Trinity::AnyPlayerInObjectRangeCheck> searcher(this, targets, check);
VisitNearbyWorldObject(GetMap()->GetVisibilityDistance(), searcher);
- for (std::list<Unit*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
+ for (std::list<Player*>::const_iterator iter = targets.begin(); iter != targets.end(); ++iter)
{
- Player *plr = dynamic_cast<Player*>(*iter);
- if(!plr)
- continue;
+ Player *plr = (*iter);
if(plr == this)
continue;
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 7305a2ac3f4..6893ac3a04a 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -16119,12 +16119,12 @@ bool Player::LoadFromDB( uint32 guid, SqlQueryHolder *holder )
return true;
}
-bool Player::isAllowedToLoot(Creature* creature)
+bool Player::isAllowedToLoot(const Creature* creature)
{
- if (creature->isDead() && !creature->IsDamageEnoughForLootingAndReward())
+ if (!creature->isDead() || !creature->IsDamageEnoughForLootingAndReward())
return false;
- Loot* loot = &creature->loot;
+ const Loot* loot = &creature->loot;
if (loot->items.size() == 0)
return false;
diff --git a/src/game/Player.h b/src/game/Player.h
index 79d75d34821..bc89f800931 100644
--- a/src/game/Player.h
+++ b/src/game/Player.h
@@ -2273,7 +2273,7 @@ class Player : public Unit, public GridObject<Player>
void SetMap(Map * map);
void ResetMap();
- bool isAllowedToLoot(Creature* creature);
+ bool isAllowedToLoot(const Creature* creature);
DeclinedName const* GetDeclinedNames() const { return m_declinedname; }
uint8 GetRunesState() const { return m_runes->runeState; }
diff --git a/src/game/SpellAuraEffects.cpp b/src/game/SpellAuraEffects.cpp
index 18377b86541..51e6a7fe4f6 100644
--- a/src/game/SpellAuraEffects.cpp
+++ b/src/game/SpellAuraEffects.cpp
@@ -6005,7 +6005,7 @@ void AuraEffect::HandleChannelDeathItem(AuraApplication const * aurApp, uint8 mo
// Soul Shard only from non-grey units
if( GetSpellProto()->EffectItemType[m_effIndex] == 6265 &&
(target->getLevel() <= Trinity::XP::GetGrayLevel(caster->getLevel()) ||
- target->GetTypeId() == TYPEID_UNIT && !caster->ToPlayer()->isAllowedToLoot(target->ToCreature())) )
+ target->GetTypeId() == TYPEID_UNIT && !target->ToCreature()->isTappedBy(caster->ToPlayer())) )
return;
//Adding items
uint32 noSpaceForCount = 0;