Fix creature tapped and lootable dynamic flags => fix creature not lootable.
Fixes issue #1067. --HG-- branch : trunk
This commit is contained in:
+22
-2
@@ -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
|
||||
|
||||
+3
-2
@@ -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)
|
||||
|
||||
+32
-16
@@ -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);
|
||||
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
@@ -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
@@ -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; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user