Index: 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 checker(ok, u_check); + + CellLock cell_lock(cell, p); + + TypeContainerVisitor, 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, 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 checker(ok, u_check); + + CellLock cell_lock(cell, p); + + TypeContainerVisitor, GridTypeMapContainer > grid_object_checker(checker); + cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); + + // or player/pet + if(!ok) + { + TypeContainerVisitor, 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 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 checker(ok, u_check); + MaNGOS::UnitListSearcher checker(targets, u_check); CellLock cell_lock(cell, p); - TypeContainerVisitor, GridTypeMapContainer > grid_object_checker(checker); + TypeContainerVisitor, 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, WorldTypeMapContainer > world_object_checker(checker); - cell_lock->Visit(cell_lock, world_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); - } + TypeContainerVisitor, 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 checker(ok, u_check); + MaNGOS::UnitListSearcher checker(targets, u_check); CellLock cell_lock(cell, p); - TypeContainerVisitor, GridTypeMapContainer > grid_object_checker(checker); + TypeContainerVisitor, GridTypeMapContainer > grid_object_checker(checker); cell_lock->Visit(cell_lock, grid_object_checker, *MapManager::Instance().GetMap(GetMapId(), this)); + TypeContainerVisitor, 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::const_iterator itr = targets.begin(); itr != targets.end(); ++itr) { - TypeContainerVisitor, 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];