diff options
Diffstat (limited to 'src/game/Player.cpp')
-rw-r--r-- | src/game/Player.cpp | 84 |
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)) ); |