Fix creature tapped and lootable dynamic flags => fix creature not lootable.

Fixes issue #1067.

--HG--
branch : trunk
This commit is contained in:
Trazom62
2010-03-14 00:22:53 +01:00
parent 274268a686
commit 6fdaf225f3
6 changed files with 62 additions and 25 deletions
+22 -2
View File
@@ -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
+2 -1
View File
@@ -529,6 +529,7 @@ class Creature : public Unit, public GridObject<Creature>
bool lootForBody;
Player *GetLootRecipient() const;
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)
+29 -13
View File
@@ -606,15 +606,33 @@ void Object::_BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask
// hide lootable animation for unallowed players
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);
else
*data << (m_uint32Values[ index ] & ~UNIT_DYNFLAG_TAPPED);
if (creature->hasLootRecipient())
{
if (creature->isTappedBy(target))
{
dynamicFlags |= (UNIT_DYNFLAG_TAPPED|UNIT_DYNFLAG_TAPPED_BY_PLAYER);
}
else
*data << m_uint32Values[ index ];
{
dynamicFlags |= UNIT_DYNFLAG_TAPPED;
dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER;
}
}
else
{
dynamicFlags &= ~UNIT_DYNFLAG_TAPPED;
dynamicFlags &= ~UNIT_DYNFLAG_TAPPED_BY_PLAYER;
}
if (!target->isAllowedToLoot(ToCreature()))
dynamicFlags &= ~UNIT_DYNFLAG_LOOTABLE;
}
*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;
+3 -3
View File
@@ -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;
+1 -1
View File
@@ -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; }
+1 -1
View File
@@ -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;