[9510] Gameobject casting improvements.

* Add IsHostileTo/IsFriendlyTo and implement expected way checks for diff. world object types.
  For controlled object check redirected to specific owner, for wild gameobject base at gameobject faction.
  If faction not set expected to be hostile to anyone.
* Update grid searchers to be usable with world object instead only unit case.
  Some grid searches lost redundent second object arg, AnyAoETargetUnitInObjectRangeCheck lost hitHidden arg
  (for hitHidden==true case added new AnyAoEVisibleTargetUnitInObjectRangeCheck)
* Updated grid searchers used with gameobject area casts now.
  Note: Gameobject area spell cast animation will still wrong show around cast triggering target instead
  center around gameobject.
* In case gameobject aura apply to target for restored use target itself as caster because
  we not have currently another way apply aura form wild gameobject.
This commit is contained in:
VladimirMangos 2010-03-04 04:04:47 +03:00
parent 52701a58f6
commit 7fb5d850bf
18 changed files with 242 additions and 54 deletions

View file

@ -26,6 +26,7 @@
#include "Opcodes.h"
#include "GossipDef.h"
#include "World.h"
#include "ObjectMgr.h"
Corpse::Corpse(CorpseType type) : WorldObject()
{
@ -232,3 +233,19 @@ bool Corpse::isVisibleForInState(Player const* u, WorldObject const* viewPoint,
{
return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(viewPoint, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
}
bool Corpse::IsHostileTo( Unit const* unit ) const
{
if (Player* owner = sObjectMgr.GetPlayer(GetOwnerGUID()))
return owner->IsHostileTo(unit);
else
return false;
}
bool Corpse::IsFriendlyTo( Unit const* unit ) const
{
if (Player* owner = sObjectMgr.GetPlayer(GetOwnerGUID()))
return owner->IsFriendlyTo(unit);
else
return true;
}

View file

@ -71,6 +71,9 @@ class Corpse : public WorldObject
void ResetGhostTime() { m_time = time(NULL); }
CorpseType GetType() const { return m_type; }
bool IsHostileTo(Unit const* unit) const;
bool IsFriendlyTo(Unit const* unit) const;
GridPair const& GetGrid() const { return m_grid; }
void SetGrid(GridPair const& grid) { m_grid = grid; }

View file

@ -161,3 +161,19 @@ bool DynamicObject::isVisibleForInState(Player const* u, WorldObject const* view
// normal case
return IsWithinDistInMap(viewPoint, World::GetMaxVisibleDistanceForObject() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false);
}
bool DynamicObject::IsHostileTo( Unit const* unit ) const
{
if (Unit* owner = GetCaster())
return owner->IsHostileTo(unit);
else
return false;
}
bool DynamicObject::IsFriendlyTo( Unit const* unit ) const
{
if (Unit* owner = GetCaster())
return owner->IsFriendlyTo(unit);
else
return true;
}

View file

@ -47,6 +47,10 @@ class DynamicObject : public WorldObject
void AddAffected(Unit *unit) { m_affected.insert(unit); }
void RemoveAffected(Unit *unit) { m_affected.erase(unit); }
void Delay(int32 delaytime);
bool IsHostileTo(Unit const* unit) const;
bool IsFriendlyTo(Unit const* unit) const;
bool isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const;
void Say(int32 textId, uint32 language, uint64 TargetGuid) { MonsterSay(textId,language,TargetGuid); }

View file

@ -1448,3 +1448,90 @@ void GameObject::UpdateRotationFields(float rotation2 /*=0.0f*/, float rotation3
SetFloatValue(GAMEOBJECT_PARENTROTATION+2, rotation2);
SetFloatValue(GAMEOBJECT_PARENTROTATION+3, rotation3);
}
bool GameObject::IsHostileTo(Unit const* unit) const
{
// always non-hostile to GM in GM mode
if(unit->GetTypeId()==TYPEID_PLAYER && ((Player const*)unit)->isGameMaster())
return false;
// test owner instead if have
if (Unit const* owner = GetOwner())
return owner->IsHostileTo(unit);
if (Unit const* targetOwner = unit->GetCharmerOrOwner())
return IsHostileTo(targetOwner);
// for not set faction case (wild object) use hostile case
if(!GetGOInfo()->faction)
return true;
// faction base cases
FactionTemplateEntry const*tester_faction = sFactionTemplateStore.LookupEntry(GetGOInfo()->faction);
FactionTemplateEntry const*target_faction = unit->getFactionTemplateEntry();
if(!tester_faction || !target_faction)
return false;
// GvP forced reaction and reputation case
if(unit->GetTypeId()==TYPEID_PLAYER)
{
// forced reaction
if(tester_faction->faction)
{
if(ReputationRank const* force = ((Player*)unit)->GetReputationMgr().GetForcedRankIfAny(tester_faction))
return *force <= REP_HOSTILE;
// apply reputation state
FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction);
if(raw_tester_faction && raw_tester_faction->reputationListID >=0 )
return ((Player const*)unit)->GetReputationMgr().GetRank(raw_tester_faction) <= REP_HOSTILE;
}
}
// common faction based case (GvC,GvP)
return tester_faction->IsHostileTo(*target_faction);
}
bool GameObject::IsFriendlyTo(Unit const* unit) const
{
// always friendly to GM in GM mode
if(unit->GetTypeId()==TYPEID_PLAYER && ((Player const*)unit)->isGameMaster())
return true;
// test owner instead if have
if (Unit const* owner = GetOwner())
return owner->IsFriendlyTo(unit);
if (Unit const* targetOwner = unit->GetCharmerOrOwner())
return IsFriendlyTo(targetOwner);
// for not set faction case (wild object) use hostile case
if(!GetGOInfo()->faction)
return false;
// faction base cases
FactionTemplateEntry const*tester_faction = sFactionTemplateStore.LookupEntry(GetGOInfo()->faction);
FactionTemplateEntry const*target_faction = unit->getFactionTemplateEntry();
if(!tester_faction || !target_faction)
return false;
// GvP forced reaction and reputation case
if(unit->GetTypeId()==TYPEID_PLAYER)
{
// forced reaction
if(tester_faction->faction)
{
if(ReputationRank const* force =((Player*)unit)->GetReputationMgr().GetForcedRankIfAny(tester_faction))
return *force >= REP_FRIENDLY;
// apply reputation state
if(FactionEntry const* raw_tester_faction = sFactionStore.LookupEntry(tester_faction->faction))
if(raw_tester_faction->reputationListID >=0 )
return ((Player const*)unit)->GetReputationMgr().GetRank(raw_tester_faction) >= REP_FRIENDLY;
}
}
// common faction based case (GvC,GvP)
return tester_faction->IsFriendlyTo(*target_faction);
}

View file

@ -677,6 +677,8 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
// 0 = use `gameobject`.`spawntimesecs`
void ResetDoorOrButton();
bool IsHostileTo(Unit const* unit) const;
bool IsFriendlyTo(Unit const* unit) const;
void SummonLinkedTrapIfAny();
void TriggeringLinkedGameObject( uint32 trapEntry, Unit* target);

View file

@ -229,10 +229,10 @@ bool CannibalizeObjectCheck::operator()(Corpse* u)
Player* owner = ObjectAccessor::FindPlayer(u->GetOwnerGUID());
if( !owner || i_funit->IsFriendlyTo(owner))
if( !owner || i_fobj->IsFriendlyTo(owner))
return false;
if(i_funit->IsWithinDistInMap(u, i_range) )
if(i_fobj->IsWithinDistInMap(u, i_range) )
return true;
return false;

View file

@ -499,34 +499,34 @@ namespace MaNGOS
class RaiseDeadObjectCheck
{
public:
RaiseDeadObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
RaiseDeadObjectCheck(Player const* fobj, float range) : i_fobj(fobj), i_range(range) {}
bool operator()(Creature* u)
{
if (i_funit->GetTypeId()!=TYPEID_PLAYER || !((Player*)i_funit)->isHonorOrXPTarget(u) ||
if (i_fobj->isHonorOrXPTarget(u) ||
u->getDeathState() != CORPSE || u->isDeadByDefault() || u->isInFlight() ||
( u->GetCreatureTypeMask() & (1 << (CREATURE_TYPE_HUMANOID-1)) )==0 ||
(u->GetDisplayId() != u->GetNativeDisplayId()))
return false;
return i_funit->IsWithinDistInMap(u, i_range);
return i_fobj->IsWithinDistInMap(u, i_range);
}
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
private:
Unit* const i_funit;
Player const* i_fobj;
float i_range;
};
class ExplodeCorpseObjectCheck
{
public:
ExplodeCorpseObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
ExplodeCorpseObjectCheck(WorldObject const* fobj, float range) : i_fobj(fobj), i_range(range) {}
bool operator()(Player* u)
{
if (u->getDeathState()!=CORPSE || u->isInFlight() ||
u->HasAuraType(SPELL_AURA_GHOST) || (u->GetDisplayId() != u->GetNativeDisplayId()))
return false;
return i_funit->IsWithinDistInMap(u, i_range);
return i_fobj->IsWithinDistInMap(u, i_range);
}
bool operator()(Creature* u)
{
@ -535,37 +535,37 @@ namespace MaNGOS
(u->GetCreatureTypeMask() & CREATURE_TYPEMASK_MECHANICAL_OR_ELEMENTAL)!=0)
return false;
return i_funit->IsWithinDistInMap(u, i_range);
return i_fobj->IsWithinDistInMap(u, i_range);
}
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
private:
Unit* const i_funit;
WorldObject const* i_fobj;
float i_range;
};
class CannibalizeObjectCheck
{
public:
CannibalizeObjectCheck(Unit* funit, float range) : i_funit(funit), i_range(range) {}
CannibalizeObjectCheck(WorldObject const* fobj, float range) : i_fobj(fobj), i_range(range) {}
bool operator()(Player* u)
{
if( i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() )
if( i_fobj->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() )
return false;
return i_funit->IsWithinDistInMap(u, i_range);
return i_fobj->IsWithinDistInMap(u, i_range);
}
bool operator()(Corpse* u);
bool operator()(Creature* u)
{
if (i_funit->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ||
if (i_fobj->IsFriendlyTo(u) || u->isAlive() || u->isInFlight() ||
(u->GetCreatureTypeMask() & CREATURE_TYPEMASK_HUMANOID_OR_UNDEAD)==0)
return false;
return i_funit->IsWithinDistInMap(u, i_range);
return i_fobj->IsWithinDistInMap(u, i_range);
}
template<class NOT_INTERESTED> bool operator()(NOT_INTERESTED*) { return false; }
private:
Unit* const i_funit;
WorldObject const* i_fobj;
float i_range;
};
@ -688,7 +688,7 @@ namespace MaNGOS
class FriendlyCCedInRange
{
public:
FriendlyCCedInRange(Unit const* obj, float range) : i_obj(obj), i_range(range) {}
FriendlyCCedInRange(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {}
bool operator()(Unit* u)
{
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
@ -699,14 +699,14 @@ namespace MaNGOS
return false;
}
private:
Unit const* i_obj;
WorldObject const* i_obj;
float i_range;
};
class FriendlyMissingBuffInRange
{
public:
FriendlyMissingBuffInRange(Unit const* obj, float range, uint32 spellid) : i_obj(obj), i_range(range), i_spell(spellid) {}
FriendlyMissingBuffInRange(WorldObject const* obj, float range, uint32 spellid) : i_obj(obj), i_range(range), i_spell(spellid) {}
bool operator()(Unit* u)
{
if(u->isAlive() && u->isInCombat() && !i_obj->IsHostileTo(u) && i_obj->IsWithinDistInMap(u, i_range) &&
@ -717,7 +717,7 @@ namespace MaNGOS
return false;
}
private:
Unit const* i_obj;
WorldObject const* i_obj;
float i_range;
uint32 i_spell;
};
@ -761,17 +761,16 @@ namespace MaNGOS
class AnyFriendlyUnitInObjectRangeCheck
{
public:
AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range) : i_obj(obj), i_funit(funit), i_range(range) {}
AnyFriendlyUnitInObjectRangeCheck(WorldObject const* obj, float range) : i_obj(obj), i_range(range) {}
bool operator()(Unit* u)
{
if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_funit->IsFriendlyTo(u))
if(u->isAlive() && i_obj->IsWithinDistInMap(u, i_range) && i_obj->IsFriendlyTo(u))
return true;
else
return false;
}
private:
WorldObject const* i_obj;
Unit const* i_funit;
float i_range;
};
@ -816,11 +815,11 @@ namespace MaNGOS
NearestAttackableUnitInObjectRangeCheck(NearestAttackableUnitInObjectRangeCheck const&);
};
class AnyAoETargetUnitInObjectRangeCheck
class AnyAoEVisibleTargetUnitInObjectRangeCheck
{
public:
AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range, bool hitHidden = true)
: i_obj(obj), i_funit(funit), i_range(range), i_hitHidden(hitHidden)
AnyAoEVisibleTargetUnitInObjectRangeCheck(WorldObject const* obj, Unit const* funit, float range)
: i_obj(obj), i_funit(funit), i_range(range)
{
Unit const* check = i_funit;
Unit const* owner = i_funit->GetOwner();
@ -835,7 +834,7 @@ namespace MaNGOS
return false;
if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem())
return false;
if (!i_hitHidden && !u->isVisibleForOrDetect(i_funit, i_funit, false))
if (!u->isVisibleForOrDetect(i_funit, i_funit, false))
return false;
if(( i_targetForPlayer ? !i_funit->IsFriendlyTo(u) : i_funit->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range))
@ -848,7 +847,36 @@ namespace MaNGOS
WorldObject const* i_obj;
Unit const* i_funit;
float i_range;
bool i_hitHidden;
};
class AnyAoETargetUnitInObjectRangeCheck
{
public:
AnyAoETargetUnitInObjectRangeCheck(WorldObject const* obj, float range)
: i_obj(obj), i_range(range)
{
i_targetForPlayer = i_obj->IsControlledByPlayer();
}
bool operator()(Unit* u)
{
// Check contains checks for: live, non-selectable, non-attackable flags, flight check and GM check, ignore totems
if (!u->isTargetableForAttack())
return false;
if(u->GetTypeId()==TYPEID_UNIT && ((Creature*)u)->isTotem())
return false;
if(( i_targetForPlayer ? !i_obj->IsFriendlyTo(u) : i_obj->IsHostileTo(u) )&& i_obj->IsWithinDistInMap(u, i_range))
return true;
return false;
}
private:
bool i_targetForPlayer;
WorldObject const* i_obj;
float i_range;
};
// do attack at call of help to friendly crearture
@ -877,6 +905,7 @@ namespace MaNGOS
if (u->AI())
u->AI()->AttackStart(i_enemy);
}
private:
Unit* const i_funit;
Unit* const i_enemy;

View file

@ -1958,3 +1958,21 @@ void WorldObject::BuildUpdateData( UpdateDataMapType & update_players)
ClearUpdateMask(false);
}
bool WorldObject::IsControlledByPlayer() const
{
switch (GetTypeId())
{
case TYPEID_GAMEOBJECT:
return IS_PLAYER_GUID(((GameObject*)this)->GetOwnerGUID());
case TYPEID_UNIT:
case TYPEID_PLAYER:
return ((Unit*)this)->IsCharmerOrOwnerPlayerOrPlayerItself();
case TYPEID_DYNAMICOBJECT:
return IS_PLAYER_GUID(((DynamicObject*)this)->GetCasterGUID());
case TYPEID_CORPSE:
return true;
default:
return false;
}
}

View file

@ -91,6 +91,7 @@ class UpdateData;
class WorldSession;
class Creature;
class Player;
class Unit;
class Map;
class UpdateMask;
class InstanceData;
@ -472,6 +473,10 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void SendObjectDeSpawnAnim(uint64 guid);
void SendGameObjectCustomAnim(uint64 guid);
virtual bool IsHostileTo(Unit const* unit) const =0;
virtual bool IsFriendlyTo(Unit const* unit) const =0;
bool IsControlledByPlayer() const;
virtual void SaveRespawnTime() {}
void AddObjectToRemoveList();

View file

@ -19771,7 +19771,7 @@ uint32 Player::GetResurrectionSpellId()
}
// Used in triggers for check "Only to targets that grant experience or honor" req
bool Player::isHonorOrXPTarget(Unit* pVictim)
bool Player::isHonorOrXPTarget(Unit* pVictim) const
{
uint32 v_level = pVictim->getLevel();
uint32 k_grey = MaNGOS::XP::GetGrayLevel(getLevel());

View file

@ -1895,7 +1895,7 @@ class MANGOS_DLL_SPEC Player : public Unit
bool IsAtGroupRewardDistance(WorldObject const* pRewardSource) const;
bool RewardPlayerAndGroupAtKill(Unit* pVictim);
void RewardPlayerAndGroupAtEvent(uint32 creature_id,WorldObject* pRewardSource);
bool isHonorOrXPTarget(Unit* pVictim);
bool isHonorOrXPTarget(Unit* pVictim) const;
ReputationMgr& GetReputationMgr() { return m_reputationMgr; }
ReputationMgr const& GetReputationMgr() const { return m_reputationMgr; }

View file

@ -1445,7 +1445,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
std::list<Unit *> tempTargetUnitMap;
{
MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(m_caster, m_caster, max_range);
MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(m_caster, max_range);
MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck> searcher(m_caster, tempTargetUnitMap, u_check);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
@ -1514,7 +1514,7 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
cell.SetNoCreate();
std::list<Unit*> tempTargetUnitMap;
{
MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, m_caster, max_range);
MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(m_caster, max_range);
MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck> searcher(m_caster, tempTargetUnitMap, u_check);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
@ -1610,10 +1610,10 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
std::list<Unit *> tempTargetUnitMap;
{
MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(pUnitTarget, originalCaster, max_range, false);
MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck> searcher(m_caster, tempTargetUnitMap, u_check);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer> world_unit_searcher(searcher);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer> grid_unit_searcher(searcher);
MaNGOS::AnyAoEVisibleTargetUnitInObjectRangeCheck u_check(pUnitTarget, originalCaster, max_range);
MaNGOS::UnitListSearcher<MaNGOS::AnyAoEVisibleTargetUnitInObjectRangeCheck> searcher(m_caster, tempTargetUnitMap, u_check);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoEVisibleTargetUnitInObjectRangeCheck>, WorldTypeMapContainer> world_unit_searcher(searcher);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoEVisibleTargetUnitInObjectRangeCheck>, GridTypeMapContainer> grid_unit_searcher(searcher);
cell.Visit(p, world_unit_searcher, *m_caster->GetMap(), *pUnitTarget, max_range);
cell.Visit(p, grid_unit_searcher, *m_caster->GetMap(), *pUnitTarget, max_range);
@ -3170,20 +3170,20 @@ void Spell::SendCastResult(Player* caster, SpellEntry const* spellInfo, uint8 ca
void Spell::SendSpellStart()
{
if(!IsNeedSendToClient())
if (!IsNeedSendToClient())
return;
sLog.outDebug("Sending SMSG_SPELL_START id=%u", m_spellInfo->Id);
uint32 castFlags = CAST_FLAG_UNKNOWN1;
if(IsRangedSpell())
if (IsRangedSpell())
castFlags |= CAST_FLAG_AMMO;
if(m_spellInfo->runeCostID)
if (m_spellInfo->runeCostID)
castFlags |= CAST_FLAG_UNKNOWN10;
WorldPacket data(SMSG_SPELL_START, (8+8+4+4+2));
if(m_CastItem)
if (m_CastItem)
data.append(m_CastItem->GetPackGUID());
else
data.append(m_caster->GetPackGUID());

View file

@ -620,12 +620,12 @@ namespace MaNGOS
Spell &i_spell;
const uint32& i_index;
float i_radius;
Unit* i_originalCaster;
WorldObject* i_originalCaster;
SpellNotifierPlayer(Spell &spell, std::list<Unit*> &data, const uint32 &i, float radius)
: i_data(data), i_spell(spell), i_index(i), i_radius(radius)
{
i_originalCaster = i_spell.GetAffectiveCaster();
i_originalCaster = i_spell.GetCastingObject();
}
void Visit(PlayerMapType &m)
@ -656,13 +656,15 @@ namespace MaNGOS
SpellNotifyPushType i_push_type;
float i_radius;
SpellTargets i_TargetType;
Unit* i_originalCaster;
WorldObject* i_originalCaster;
bool i_playerControled;
SpellNotifierCreatureAndPlayer(Spell &spell, std::list<Unit*> &data, float radius, SpellNotifyPushType type,
SpellTargets TargetType = SPELL_TARGETS_NOT_FRIENDLY)
: i_data(&data), i_spell(spell), i_push_type(type), i_radius(radius), i_TargetType(TargetType)
{
i_originalCaster = spell.GetAffectiveCaster();
i_originalCaster = spell.GetCastingObject();
i_playerControled = i_originalCaster->IsControlledByPlayer();
}
template<class T> inline void Visit(GridRefManager<T> &m)
@ -704,16 +706,14 @@ namespace MaNGOS
if(itr->getSource()->GetTypeId()==TYPEID_UNIT && ((Creature*)itr->getSource())->isTotem())
continue;
Unit* check = i_originalCaster->GetCharmerOrOwnerOrSelf();
if( check->GetTypeId()==TYPEID_PLAYER )
if (i_playerControled)
{
if (check->IsFriendlyTo( itr->getSource() ))
if (i_originalCaster->IsFriendlyTo( itr->getSource() ))
continue;
}
else
{
if (!check->IsHostileTo( itr->getSource() ))
if (!i_originalCaster->IsHostileTo( itr->getSource() ))
continue;
}
}

View file

@ -759,7 +759,7 @@ void AreaAura::Update(uint32 diff)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(caster, owner, m_radius);
MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(caster, m_radius);
MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck> searcher(caster,targets, u_check);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);
@ -774,7 +774,7 @@ void AreaAura::Update(uint32 diff)
cell.data.Part.reserved = ALL_DISTRICT;
cell.SetNoCreate();
MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(caster, owner, m_radius); // No GetCharmer in searcher
MaNGOS::AnyAoETargetUnitInObjectRangeCheck u_check(caster, m_radius); // No GetCharmer in searcher
MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck> searcher(caster, targets, u_check);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyAoETargetUnitInObjectRangeCheck>, GridTypeMapContainer > grid_unit_searcher(searcher);

View file

@ -2826,7 +2826,14 @@ void Spell::EffectApplyAura(SpellEffectIndex eff_idx)
Unit* caster = GetAffectiveCaster();
if(!caster)
{
// FIXME: currently we can't have auras applied explIcitly by gameobjects
// so for auras from wild gameobjects (no owner) target used
if (IS_GAMEOBJECT_GUID(m_originalCasterGUID))
caster = unitTarget;
else
return;
}
sLog.outDebug("Spell: Aura is: %u", m_spellInfo->EffectApplyAuraName[eff_idx]);

View file

@ -12896,7 +12896,7 @@ Unit* Unit::SelectRandomFriendlyTarget(Unit* except /*= NULL*/, float radius /*=
std::list<Unit *> targets;
MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(this, this, radius);
MaNGOS::AnyFriendlyUnitInObjectRangeCheck u_check(this, radius);
MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck> searcher(this, targets, u_check);
TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyFriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_unit_searcher(searcher);

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "9509"
#define REVISION_NR "9510"
#endif // __REVISION_NR_H__