rendered paste bodyIndex: src/game/GameObject.cpp
===================================================================
--- src/game/GameObject.cpp (revision 5533)
+++ src/game/GameObject.cpp (working copy)
@@ -254,17 +254,86 @@
{
// traps
Unit* owner = GetOwner();
- Unit* ok = NULL; // pointer to appropriate target if found any
if(m_environmentcastTime >= time(NULL))
return;
- float radius = goInfo->trap.radius;
- if(!radius) // cast in other case (at some triggering/linked go/etc explicit call)
+ float originalActivationRadius = goInfo->trap.radius;
+ if(!originalActivationRadius) // cast in other case (at some triggering/linked go/etc explicit call)
return;
bool NeedDespawn = (goInfo->trap.isNeedDespawn != 0);
+ // activate GO if targets present in activation radius
+ if(m_environmentcastTime==0)
+ {
+ Unit* ok = NULL;
+
+ CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY()));
+ Cell cell(p);
+ cell.data.Part.reserved = ALL_DISTRICT;
+
+ if(owner && NeedDespawn) // hunter trap
+ {
+ MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, originalActivationRadius);
+ MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(ok, u_check);
+
+ CellLock<GridReadGuard> cell_lock(cell, p);
+
+ TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
+ cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
+
+ // or unfriendly player/pet
+ if(!ok)
+ {
+ TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
+ cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
+ }
+ }
+ else // environmental trap
+ {
+ // environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support
+ MaNGOS::AnyUnitInObjectRangeCheck u_check(this, originalActivationRadius);
+ MaNGOS::UnitSearcher<MaNGOS::AnyUnitInObjectRangeCheck> checker(ok, u_check);
+
+ CellLock<GridReadGuard> cell_lock(cell, p);
+
+ TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
+ cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
+
+ // or player/pet
+ if(!ok)
+ {
+ TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
+ cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
+ }
+ }
+
+ if (!ok)
+ return;
+
+ m_environmentcastTime = time(NULL); // trap activated
+ }
+
+ SpellEntry const* trapSpellInfo = sSpellStore.LookupEntry(goInfo->trap.spellId);
+ if(!trapSpellInfo)
+ return;
+
+ // use spell radius for cast targets selection
+ // we do radius selection in hack way (max from effect radius) until cast spell to player itself
+ // and then all effects will applied with same max radius instead correct different radius for each effect
+ float radius = 0;
+ for(int i = 0; i <3; ++i)
+ if(trapSpellInfo->Effect[i])
+ if(trapSpellInfo->EffectRadiusIndex[i])
+ if(float eRadius = GetSpellRadius(sSpellRadiusStore.LookupEntry(trapSpellInfo->EffectRadiusIndex[i])))
+ if(eRadius > radius)
+ radius = eRadius;
+ if(!radius)
+ radius = GetSpellMaxRange(sSpellRangeStore.LookupEntry(trapSpellInfo->rangeIndex));
+
+ std::list<Unit*> targets;
+
CellPair p(MaNGOS::ComputeCellPair(GetPositionX(),GetPositionY()));
Cell cell(p);
cell.data.Part.reserved = ALL_DISTRICT;
@@ -274,44 +343,38 @@
if(owner && NeedDespawn) // hunter trap
{
MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck u_check(this, owner, radius);
- MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(ok, u_check);
+ MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck> checker(targets, u_check);
CellLock<GridReadGuard> cell_lock(cell, p);
- TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
+ TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
-
- // or unfriendly player/pet
- if(!ok)
- {
- TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
- cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
- }
+ TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnfriendlyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
+ cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
}
else // environmental trap
{
// environmental damage spells already have around enemies targeting but this not help in case not existed GO casting support
MaNGOS::AnyUnitInObjectRangeCheck u_check(this, radius);
- MaNGOS::UnitSearcher<MaNGOS::AnyUnitInObjectRangeCheck> checker(ok, u_check);
+ MaNGOS::UnitListSearcher<MaNGOS::AnyUnitInObjectRangeCheck> checker(targets, u_check);
CellLock<GridReadGuard> cell_lock(cell, p);
- TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
+ TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, GridTypeMapContainer > grid_object_checker(checker);
cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
+ TypeContainerVisitor<MaNGOS::UnitListSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
+ cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
+ }
- // or player/pet
- if(!ok)
+ if (!targets.empty())
+ {
+ for(std::list<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr)
{
- TypeContainerVisitor<MaNGOS::UnitSearcher<MaNGOS::AnyUnitInObjectRangeCheck>, WorldTypeMapContainer > world_object_checker(checker);
- cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this));
+ Unit *caster = owner ? owner : *itr;
+
+ caster->CastSpell(*itr, goInfo->trap.spellId, true);
}
- }
- if (ok)
- {
- Unit *caster = owner ? owner : ok;
-
- caster->CastSpell(ok, goInfo->trap.spellId, true);
m_environmentcastTime = time(NULL) + 4; // 4 seconds
if(NeedDespawn)
Index: src/game/GameObject.h
===================================================================
--- src/game/GameObject.h (revision 5533)
+++ src/game/GameObject.h (working copy)
@@ -77,7 +77,7 @@
{
uint32 _data0; //0 lockid???
uint32 _data1;
- uint32 radius; //2
+ uint32 radius; //2 radius for trap activation
uint32 spellId; //3
uint32 isNeedDespawn; //4 (if >0)
uint32 _data5[7];