All pastes #968370 Raw Edit

Miscellany

public text v1 · immutable
·published 2008-04-03 00:04 UTC
rendered paste body
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<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];