mirror of
https://github.com/mangosfour/server.git
synced 2025-12-14 16:37:01 +00:00
Merge commit 'origin/master' into 310
Conflicts: src/game/AchievementMgr.cpp src/game/BattleGroundHandler.cpp src/game/CreatureEventAIMgr.cpp src/game/DBCStructure.h src/game/Player.cpp src/game/Spell.cpp src/shared/revision_nr.h
This commit is contained in:
commit
a9e148edac
45 changed files with 1119 additions and 298 deletions
|
|
@ -1592,7 +1592,7 @@ bool Player::TeleportTo(uint32 mapid, float x, float y, float z, float orientati
|
|||
// ObjectAccessor won't find the flag.
|
||||
if (duel && GetMapId()!=mapid)
|
||||
{
|
||||
GameObject* obj = ObjectAccessor::GetGameObject(*this, GetUInt64Value(PLAYER_DUEL_ARBITER));
|
||||
GameObject* obj = GetMap()->GetGameObject(GetUInt64Value(PLAYER_DUEL_ARBITER));
|
||||
if (obj)
|
||||
DuelComplete(DUEL_FLED);
|
||||
}
|
||||
|
|
@ -1947,6 +1947,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 = GetMap()->GetCreature(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 = GetMap()->GetGameObject(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() &&
|
||||
|
|
@ -2805,6 +2887,9 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
|
||||
SpellLearnSkillNode const* spellLearnSkill = spellmgr.GetSpellLearnSkill(spell_id);
|
||||
|
||||
SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id);
|
||||
SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id);
|
||||
|
||||
if(spellLearnSkill)
|
||||
{
|
||||
uint32 skill_value = GetPureSkillValue(spellLearnSkill->skill);
|
||||
|
|
@ -2823,9 +2908,6 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
else
|
||||
{
|
||||
// not ranked skills
|
||||
SkillLineAbilityMap::const_iterator lower = spellmgr.GetBeginSkillLineAbilityMap(spell_id);
|
||||
SkillLineAbilityMap::const_iterator upper = spellmgr.GetEndSkillLineAbilityMap(spell_id);
|
||||
|
||||
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
|
||||
{
|
||||
SkillLineEntry const *pSkill = sSkillLineStore.LookupEntry(_spell_idx->second->skillId);
|
||||
|
|
@ -2872,10 +2954,16 @@ bool Player::addSpell(uint32 spell_id, bool active, bool learning, bool dependen
|
|||
}
|
||||
}
|
||||
|
||||
if(IsInWorld())
|
||||
if(!GetSession()->PlayerLoading())
|
||||
{
|
||||
// not ranked skills
|
||||
for(SkillLineAbilityMap::const_iterator _spell_idx = lower; _spell_idx != upper; ++_spell_idx)
|
||||
{
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILL_LINE,_spell_idx->second->skillId);
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS,_spell_idx->second->skillId);
|
||||
}
|
||||
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SPELL,spell_id);
|
||||
GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_LEARN_SKILLLINE_SPELLS,spell_id);
|
||||
}
|
||||
|
||||
// return true (for send learn packet) only if spell active (in case ranked spells) and not replace old spell
|
||||
|
|
@ -6034,7 +6122,7 @@ void Player::CheckDuelDistance(time_t currTime)
|
|||
return;
|
||||
|
||||
uint64 duelFlagGUID = GetUInt64Value(PLAYER_DUEL_ARBITER);
|
||||
GameObject* obj = ObjectAccessor::GetGameObject(*this, duelFlagGUID);
|
||||
GameObject* obj = GetMap()->GetGameObject(duelFlagGUID);
|
||||
if(!obj)
|
||||
return;
|
||||
|
||||
|
|
@ -6101,7 +6189,7 @@ void Player::DuelComplete(DuelCompleteType type)
|
|||
duel->opponent->GetSession()->SendPacket(&data);*/
|
||||
|
||||
//Remove Duel Flag object
|
||||
GameObject* obj = ObjectAccessor::GetGameObject(*this, GetUInt64Value(PLAYER_DUEL_ARBITER));
|
||||
GameObject* obj = GetMap()->GetGameObject(GetUInt64Value(PLAYER_DUEL_ARBITER));
|
||||
if(obj)
|
||||
duel->initiator->RemoveGameObject(obj,true);
|
||||
|
||||
|
|
@ -7006,8 +7094,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
if (IS_GAMEOBJECT_GUID(guid))
|
||||
{
|
||||
sLog.outDebug(" IS_GAMEOBJECT_GUID(guid)");
|
||||
GameObject *go =
|
||||
ObjectAccessor::GetGameObject(*this, guid);
|
||||
GameObject *go = GetMap()->GetGameObject(guid);
|
||||
|
||||
// not check distance for GO in case owned GO (fishing bobber case, for example)
|
||||
// And permit out of range GO with no owner in case fishing hole
|
||||
|
|
@ -7120,7 +7207,7 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
|
|||
}
|
||||
else
|
||||
{
|
||||
Creature *creature = ObjectAccessor::GetCreature(*this, guid);
|
||||
Creature *creature = GetMap()->GetCreature(guid);
|
||||
|
||||
// must be in range and creature must be alive for pickpocket and must be dead for another loot
|
||||
if (!creature || creature->isAlive()!=(loot_type == LOOT_PICKPOCKETING) || !creature->IsWithinDistInMap(this,INTERACTION_DISTANCE))
|
||||
|
|
@ -11714,7 +11801,7 @@ void Player::PrepareQuestMenu( uint64 guid )
|
|||
Object *pObject;
|
||||
QuestRelations* pObjectQR;
|
||||
QuestRelations* pObjectQIR;
|
||||
Creature *pCreature = ObjectAccessor::GetCreature(*this, guid);
|
||||
Creature *pCreature = GetMap()->GetCreature(guid);
|
||||
if( pCreature )
|
||||
{
|
||||
pObject = (Object*)pCreature;
|
||||
|
|
@ -11723,7 +11810,7 @@ void Player::PrepareQuestMenu( uint64 guid )
|
|||
}
|
||||
else
|
||||
{
|
||||
GameObject *pGameObject = ObjectAccessor::GetGameObject(*this, guid);
|
||||
GameObject *pGameObject = GetMap()->GetGameObject(guid);
|
||||
if( pGameObject )
|
||||
{
|
||||
pObject = (Object*)pGameObject;
|
||||
|
|
@ -11800,7 +11887,7 @@ void Player::SendPreparedQuest( uint64 guid )
|
|||
qe._Delay = 0;
|
||||
qe._Emote = 0;
|
||||
std::string title = "";
|
||||
Creature *pCreature = ObjectAccessor::GetCreature(*this, guid);
|
||||
Creature *pCreature = GetMap()->GetCreature(guid);
|
||||
if( pCreature )
|
||||
{
|
||||
uint32 textid = pCreature->GetNpcTextId();
|
||||
|
|
@ -11864,7 +11951,7 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest )
|
|||
QuestRelations* pObjectQR;
|
||||
QuestRelations* pObjectQIR;
|
||||
|
||||
Creature *pCreature = ObjectAccessor::GetCreature(*this, guid);
|
||||
Creature *pCreature = GetMap()->GetCreature(guid);
|
||||
if( pCreature )
|
||||
{
|
||||
pObject = (Object*)pCreature;
|
||||
|
|
@ -11873,7 +11960,7 @@ Quest const * Player::GetNextQuest( uint64 guid, Quest const *pQuest )
|
|||
}
|
||||
else
|
||||
{
|
||||
GameObject *pGameObject = ObjectAccessor::GetGameObject(*this, guid);
|
||||
GameObject *pGameObject = GetMap()->GetGameObject(guid);
|
||||
if( pGameObject )
|
||||
{
|
||||
pObject = (Object*)pGameObject;
|
||||
|
|
@ -16799,7 +16886,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)) );
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue