diff options
author | Trazom62 <none@none> | 2010-03-14 00:22:53 +0100 |
---|---|---|
committer | Trazom62 <none@none> | 2010-03-14 00:22:53 +0100 |
commit | 6fdaf225f3bb9ce84e74f40e56727ccfea729a38 (patch) | |
tree | 381d341248fc721a4f9255c5756736560caaea54 | |
parent | 274268a68643c949cd914229fe31e98dc4c862c4 (diff) |
Fix creature tapped and lootable dynamic flags => fix creature not lootable.
Fixes issue #1067.
--HG--
branch : trunk
-rw-r--r-- | src/game/Creature.cpp | 24 | ||||
-rw-r--r-- | src/game/Creature.h | 5 | ||||
-rw-r--r-- | src/game/Object.cpp | 48 | ||||
-rw-r--r-- | src/game/Player.cpp | 6 | ||||
-rw-r--r-- | src/game/Player.h | 2 | ||||
-rw-r--r-- | src/game/SpellAuraEffects.cpp | 2 |
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; |