aboutsummaryrefslogtreecommitdiff
path: root/src/game/Player.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r--src/game/Player.cpp84
1 files changed, 83 insertions, 1 deletions
diff --git a/src/game/Player.cpp b/src/game/Player.cpp
index 71936933a8b..bfe682db204 100644
--- a/src/game/Player.cpp
+++ b/src/game/Player.cpp
@@ -2011,6 +2011,88 @@ bool Player::CanInteractWithNPCs(bool alive) const
return true;
}
+Creature*
+Player::GetNPCIfCanInteractWith(uint64 guid, uint32 npcflagmask)
+{
+ // unit checks
+ if (!guid)
+ return NULL;
+
+ if(!IsInWorld())
+ return NULL;
+
+ // exist
+ Creature *unit = ObjectAccessor::GetCreature(*this,guid);
+ if (!unit)
+ return NULL;
+
+ // player check
+ if(!CanInteractWithNPCs(!unit->isSpiritService()))
+ return NULL;
+
+ // appropriate npc type
+ if(npcflagmask && !unit->HasFlag( UNIT_NPC_FLAGS, npcflagmask ))
+ return NULL;
+
+ // alive or spirit healer
+ if(!unit->isAlive() && (!unit->isSpiritService() || isAlive() ))
+ return NULL;
+
+ // not allow interaction under control
+ if(unit->GetCharmerOrOwnerGUID())
+ return NULL;
+
+ // not enemy
+ if( unit->IsHostileTo(this))
+ return NULL;
+
+ // not unfriendly
+ if(FactionTemplateEntry const* factionTemplate = sFactionTemplateStore.LookupEntry(unit->getFaction()))
+ if(factionTemplate->faction)
+ if(FactionEntry const* faction = sFactionStore.LookupEntry(factionTemplate->faction))
+ if(faction->reputationListID >= 0 && GetReputationMgr().GetRank(faction) <= REP_UNFRIENDLY)
+ return NULL;
+
+ // not too far
+ if(!unit->IsWithinDistInMap(this,INTERACTION_DISTANCE))
+ return NULL;
+
+ return unit;
+}
+
+GameObject* Player::GetGameObjectIfCanInteractWith(uint64 guid, GameobjectTypes type) const
+{
+ if(GameObject *go = ObjectAccessor::GetGameObject(*this,guid))
+ {
+ if(go->GetGoType() == type)
+ {
+ float maxdist;
+ switch(type)
+ {
+ // TODO: find out how the client calculates the maximal usage distance to spellless working
+ // gameobjects like guildbanks and mailboxes - 10.0 is a just an abitrary choosen number
+ case GAMEOBJECT_TYPE_GUILD_BANK:
+ case GAMEOBJECT_TYPE_MAILBOX:
+ maxdist = 10.0f;
+ break;
+ case GAMEOBJECT_TYPE_FISHINGHOLE:
+ maxdist = 20.0f+CONTACT_DISTANCE; // max spell range
+ break;
+ default:
+ maxdist = INTERACTION_DISTANCE;
+ break;
+ }
+
+ if (go->IsWithinDistInMap(this, maxdist))
+ return go;
+
+ sLog.outError("IsGameObjectOfTypeInRange: GameObject '%s' [GUID: %u] is too far away from player %s [GUID: %u] to be used by him (distance=%f, maximal 10 is allowed)", go->GetGOInfo()->name,
+ go->GetGUIDLow(), GetName(), GetGUIDLow(), go->GetDistance(this));
+ }
+ }
+ return NULL;
+}
+
bool Player::IsUnderWater() const
{
return IsInWater() &&
@@ -17260,7 +17342,7 @@ bool Player::BuyItemFromVendor(uint64 vendorguid, uint32 item, uint8 count, uint
return false;
}
- Creature *pCreature = ObjectAccessor::GetNPCIfCanInteractWith(*this, vendorguid,UNIT_NPC_FLAG_VENDOR);
+ Creature *pCreature = GetNPCIfCanInteractWith(vendorguid,UNIT_NPC_FLAG_VENDOR);
if (!pCreature)
{
sLog.outDebug( "WORLD: BuyItemFromVendor - Unit (GUID: %u) not found or you can't interact with him.", uint32(GUID_LOPART(vendorguid)) );