Показать сообщение отдельно
Старый 07.03.2010, 15:26   #2
Gen1us2k
RMDC Donator
 
Аватар для Gen1us2k
 
Регистрация: 07.03.2010
Адрес: Кыргызстан
Сообщений: 52
Сказал(а) спасибо: 18
Поблагодарили 45 раз(а) в 11 сообщениях
Gen1us2k Скоро придёт к известности
По умолчанию

Код:
diff --git a/src/game/Cell.h b/src/game/Cell.h
index 10ec221..d12f346 100644
--- a/src/game/Cell.h
+++ b/src/game/Cell.h
@@ -160,8 +160,10 @@ struct MANGOS_DLL_DECL Cell
 
     template<class T, class CONTAINER> void Visit(const CellPair &cellPair, TypeContainerVisitor<T, CONTAINER> &visitor, Map &) const;
     template<class T, class CONTAINER> void Visit(const CellPair &cellPair, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, const WorldObject &obj, float radius) const;
+    template<class T, class CONTAINER> void Visit(const CellPair &cellPair, TypeContainerVisitor<T, CONTAINER> &visitor, Map &, float radius, float x_off, float y_off) const;
 
     static CellArea CalculateCellArea(const WorldObject &obj, float radius);
+    static CellArea CalculateCellArea(float x, float y, float radius);
 
 private:
     template<class T, class CONTAINER> void VisitCircle(const CellPair &cellPair, TypeContainerVisitor<T, CONTAINER> &, Map &, const CellPair& , const CellPair& ) const;
diff --git a/src/game/CellImpl.h b/src/game/CellImpl.h
index a6be9f0..c8400bb 100644
--- a/src/game/CellImpl.h
+++ b/src/game/CellImpl.h
@@ -279,4 +279,49 @@ Cell::VisitCircle(const CellPair &standing_cell, TypeContainerVisitor<T, CONTAIN
     }
 }
 
+template<class T, class CONTAINER>
+inline void
+Cell::Visit(const CellPair &standing_cell, TypeContainerVisitor<T, CONTAINER> &visitor, Map &m, float radius, float x_off, float y_off) const
+{
+    if (standing_cell.x_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP || standing_cell.y_coord >= TOTAL_NUMBER_OF_CELLS_PER_MAP)
+        return;
+
+    int left = 0, right = 0, upper = 0, lower = 0;
+
+    // Origin = (CENTER_GRID_CELL_OFFSET, CENTER_GRID_CELL_OFFSET)
+    if(CENTER_GRID_CELL_OFFSET - x_off < radius)
+        ++right;
+    if(CENTER_GRID_CELL_OFFSET + x_off < radius)
+        ++left;
+    if(CENTER_GRID_CELL_OFFSET - y_off < radius)
+        ++upper;
+    if(CENTER_GRID_CELL_OFFSET + y_off < radius)
+        ++lower;
+
+    if(!left && !right && !upper && !lower)
+    {
+        m.Visit(*this, visitor);
+        return;
+    }                
+
+    CellPair begin_cell = standing_cell;
+    CellPair end_cell = standing_cell;
+
+    begin_cell << left; //note: need change << if left > 1
+    begin_cell -= lower;
+    end_cell >> right;
+    end_cell += upper;
+
+    // loop the cell range
+    for(uint32 x = begin_cell.x_coord; x <= end_cell.x_coord; x++)
+    {
+        for(uint32 y = begin_cell.y_coord; y <= end_cell.y_coord; y++)
+        {
+            CellPair cell_pair(x,y);
+            Cell r_zone(cell_pair);
+            r_zone.data.Part.nocreate = data.Part.nocreate;
+            m.Visit(r_zone, visitor);
+        }
+    }
+}
 #endif
diff --git a/src/game/DBCStructure.h b/src/game/DBCStructure.h
index 30d000f..fbede52 100644
--- a/src/game/DBCStructure.h
+++ b/src/game/DBCStructure.h
@@ -844,9 +844,14 @@ struct GameObjectDisplayInfoEntry
 {
     uint32      Displayid;                                  // 0        m_ID
     // char* filename;                                      // 1
-    // uint32 unknown2[10];                                 // 2-11     unknown data
-    // float  unknown12[6];                                 // 12-17    unknown data
-    // uint32 unknown18;                                    // 18       unknown data
+    //uint32  unk1[10];   //2-11
+    float   minX;
+    float   minY;
+    float   minZ;
+    float   maxX;
+    float   maxY;
+    float   maxZ;
+    //uint32  transport;  //18
 };
 
 struct GemPropertiesEntry
diff --git a/src/game/GameObject.cpp b/src/game/GameObject.cpp
index b75076a..5a784f5 100644
--- a/src/game/GameObject.cpp
+++ b/src/game/GameObject.cpp
@@ -151,6 +151,9 @@ bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMa
     SetGoArtKit(0);                                         // unknown what this is
     SetGoAnimProgress(animprogress);
 
+    if(goinfo->type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
+        m_health = goinfo->destructibleBuilding.damagedHealth;
+
     //Notify the map's instance data.
     //Only works if you create the object in it, not if it is moves to that map.
     //Normally non-players do not teleport to other maps.
@@ -1000,6 +1003,11 @@ void GameObject::Use(Unit* user)
                 {
                     sLog.outDebug("Goober ScriptStart id %u for GO entry %u (GUID %u).", info->goober.eventId, GetEntry(), GetDBTableGUIDLow());
                     GetMap()->ScriptsStart(sEventScripts, info->goober.eventId, player, this);
+					////////////////// Strand of the Ancients ///////////////////
+					/*if (player->CanUseBattleGroundObject())
+    					if (BattleGround *bg = player->GetBattleGround())
+        					if (bg->GetTypeID() == BATTLEGROUND_SA)
+           	 				bg->EventPlayerDamegeGO(player, this, info->goober.eventId);*/
                 }
 
                 // possible quest objective for active quests
@@ -1349,6 +1357,120 @@ void GameObject::Use(Unit* user)
     spell->prepare(&targets);
 }
 
+bool GameObject::IsInRange(float x, float y, float z, float radius) const
+{
+    GameObjectDisplayInfoEntry const * info = sGameObjectDisplayInfoStore.LookupEntry(GetUInt32Value(GAMEOBJECT_DISPLAYID));
+    if(!info)
+        return IsWithinDist3d(x, y, z, radius);
+
+    float sinA = sin(GetOrientation());
+    float cosA = cos(GetOrientation());
+    float dx = x - GetPositionX();
+    float dy = y - GetPositionY();
+    float dz = z - GetPositionZ();
+    float dist = sqrt(dx*dx + dy*dy);
+    float sinB = dx / dist;
+    float cosB = dy / dist;
+    dx = dist * (cosA * cosB + sinA * sinB);
+    dy = dist * (cosA * sinB - sinA * cosB);
+    return dx < info->maxX + radius && dx > info->minX - radius
+        && dy < info->maxY + radius && dy > info->minY - radius
+        && dz < info->maxZ + radius && dz > info->minZ - radius;
+}
+
+void GameObject::TakenDamage(uint32 damage, Unit* pKiller)
+{
+    if(!m_health)
+        return;
+
+    if(m_health > damage)
+    {
+        m_health -= damage;
+        return;
+    }
+
+    m_health = 0;
+
+	if (HasFlag(GAMEOBJECT_FLAGS,GO_FLAG_DAMAGED) && !HasFlag(GAMEOBJECT_FLAGS,GO_FLAG_DESTROYED)) // from damaged to destroyed
+	{
+		RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED);
+		SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DESTROYED);
+		SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->destructibleBuilding.destroyedDisplayId);
+		m_health = 0;
+	}
+    else if(!HasFlag(GAMEOBJECT_FLAGS,GO_FLAG_DAMAGED) && !HasFlag(GAMEOBJECT_FLAGS,GO_FLAG_DESTROYED))
+    {
+        SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED);
+        SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->destructibleBuilding.damagedDisplayId);
+        if(m_goInfo->destructibleBuilding.destroyedDisplayId)
+        {
+            m_health = m_goInfo->destructibleBuilding.destroyedHealth;
+            if(!m_health)
+                m_health = 1;
+        }
+        else
+            m_health = 0;
+    }
+}
+
+void GameObject::Rebuild(Unit* pKiller)
+{
+	RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_DAMAGED + GO_FLAG_DESTROYED);
+	SetUInt32Value(GAMEOBJECT_DISPLAYID, m_goInfo->displayId);
+	m_health = m_goInfo->destructibleBuilding.damagedHealth;
+	if (!pKiller)
+		return;
+	Player* unitPlayer;
+	if(pKiller->GetTypeId() == TYPEID_PLAYER)
+		unitPlayer = (Player*)pKiller;
+	else if(((Creature*)pKiller)->isVehicle())
+		unitPlayer = (Player*)pKiller->GetCharmerOrOwnerOrSelf();
+	else
+		unitPlayer = NULL;
+
+	if (unitPlayer->CanUseBattleGroundObject())
+		EventInform(m_goInfo->destructibleBuilding.rebuildingEvent, unitPlayer);
+}
+
 // overwrite WorldObject function for proper name localization
 const char* GameObject::GetNameForLocaleIdx(int32 loc_idx) const
 {
diff --git a/src/game/GameObject.h b/src/game/GameObject.h
index d92da00..c2ae485 100644
--- a/src/game/GameObject.h
+++ b/src/game/GameObject.h
@@ -356,17 +356,17 @@ struct GameObjectInfo
         //33 GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING
         struct
         {
-            uint32 intactNumHits;                           //0
+            uint32 damagedHealth;                           //0
             uint32 creditProxyCreature;                     //1
             uint32 empty1;                                  //2
             uint32 intactEvent;                             //3
-            uint32 empty2;                                  //4
-            uint32 damagedNumHits;                          //5
+            uint32 damagedDisplayId;                        //4
+            uint32 destroyedHealth;                         //5
             uint32 empty3;                                  //6
             uint32 empty4;                                  //7
             uint32 empty5;                                  //8
             uint32 damagedEvent;                            //9
-            uint32 empty6;                                  //10
+            uint32 destroyedDisplayId;                      //10
             uint32 empty7;                                  //11
             uint32 empty8;                                  //12
             uint32 empty9;                                  //13
@@ -687,6 +687,12 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
 
         bool isActiveObject() const { return false; }
         uint64 GetRotation() const { return m_rotation; }
+
+		bool IsInRange(float x, float y, float z, float radius) const;
+        void TakenDamage(uint32 damage, Unit* pKiller);
+        void Rebuild(Unit* pKiller);
+
     protected:
         uint32      m_spellId;
         time_t      m_respawnTime;                          // (secs) time of next respawn (or despawn if GO have owner()),
@@ -694,6 +700,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
         LootState   m_lootState;
         bool        m_spawnedByDefault;
         time_t      m_cooldownTime;                         // used as internal reaction delay time store (not state change reaction).
+		uint32      m_health;
                                                             // For traps this: spell casting cooldown, for doors/buttons: reset time.
         std::list<uint32> m_SkillupList;
 
diff --git a/src/game/GridNotifiers.h b/src/game/GridNotifiers.h
index 5c132e6..dacaed5 100644
--- a/src/game/GridNotifiers.h
+++ b/src/game/GridNotifiers.h
@@ -654,6 +654,24 @@ namespace MaNGOS
             NearestGameObjectFishingHole(NearestGameObjectFishingHole const&);
     };
 
+    class NearestGameObjectCheck
+    {
+        public:
+            NearestGameObjectCheck(WorldObject const& obj) : i_obj(obj), i_range(999) {}
+            bool operator()(GameObject* go)
+            {
+                i_range = i_obj.GetDistance(go);        // use found GO range as new range limit for next check
+                return true;
+            }
+            float GetLastRange() const { return i_range; }
+        private:
+            WorldObject const& i_obj;
+            float i_range;
+
+            // prevent clone this object
+            NearestGameObjectCheck(NearestGameObjectCheck const&);
+    };
+
     // Success at unit in range, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO)
     class NearestGameObjectEntryInObjectRangeCheck
     {
@@ -1027,6 +1045,18 @@ namespace MaNGOS
             NearestCreatureEntryWithLiveStateInObjectRangeCheck(NearestCreatureEntryWithLiveStateInObjectRangeCheck const&);
     };
 
+    class GameObjectInRangeCheck
+    {
+    public:
+        GameObjectInRangeCheck(float _x, float _y, float _z, float _range) : x(_x), y(_y), z(_z), range(_range) {}
+        bool operator() (GameObject* go)
+        {
+            return go->IsInRange(x, y, z, range);
+        }
+    private:
+        float x, y, z, range;
+    };
+
     class AnyPlayerInObjectRangeCheck
     {
     public:
diff --git a/src/game/Map.h b/src/game/Map.h
index 6e68529..0ff3799 100644
--- a/src/game/Map.h
+++ b/src/game/Map.h
@@ -406,6 +406,8 @@ class MANGOS_DLL_SPEC Map : public GridRefManager<NGridType>, public MaNGOS::Obj
         void RemoveFromActive(T* obj) { RemoveFromActiveHelper(obj); }
 
         void RemoveFromActive(Creature* obj);
+		
+		template<class NOTIFIER> void VisitGrid(const float &x, const float &y, float radius, NOTIFIER &notifier);
 
         Creature* GetCreature(uint64 guid);
         Vehicle* GetVehicle(uint64 guid);
@@ -629,4 +631,17 @@ Map::Visit(const Cell& cell, TypeContainerVisitor<T, CONTAINER> &visitor)
         getNGrid(x, y)->Visit(cell_x, cell_y, visitor);
     }
 }
-#endif
+
+template<class NOTIFIER>
+inline void
+Map::VisitGrid(const float &x, const float &y, float radius, NOTIFIER &notifier)
+{
+    CellPair p(MaNGOS::ComputeCellPair(x, y));
+    Cell cell(p);
+    cell.data.Part.reserved = ALL_DISTRICT;
+    cell.SetNoCreate();
+
+    TypeContainerVisitor<NOTIFIER, GridTypeMapContainer >  grid_object_notifier(notifier);
+    cell.Visit(p, grid_object_notifier, *this, radius, x, y);
+}
+#endif
\ No newline at end of file
diff --git a/src/game/Object.cpp b/src/game/Object.cpp
index 6d1a2b2..64f27d7 100644
--- a/src/game/Object.cpp
+++ b/src/game/Object.cpp
@@ -733,7 +733,7 @@ void Object::BuildValuesUpdate(uint8 updatetype, ByteBuffer * data, UpdateMask *
             if( updateMask->GetBit( index ) )
             {
                 // send in current format (float as float, uint32 as uint32)
-                if ( index == GAMEOBJECT_DYNAMIC )
+                if (/*false && */index == GAMEOBJECT_DYNAMIC )
                 {
                     if(IsActivateToQuest )
                     {
diff --git a/src/game/SharedDefines.h b/src/game/SharedDefines.h
index db31834..61d06d5 100644
--- a/src/game/SharedDefines.h
+++ b/src/game/SharedDefines.h
@@ -1070,6 +1070,7 @@ enum Targets
     TARGET_DYNAMIC_OBJECT_BEHIND       = 48,
     TARGET_DYNAMIC_OBJECT_LEFT_SIDE    = 49,
     TARGET_DYNAMIC_OBJECT_RIGHT_SIDE   = 50,
+	TARGET_OBJECT_AREA_SRC             = 51,
     TARGET_AREAEFFECT_CUSTOM_2         = 52,
     TARGET_CURRENT_ENEMY_COORDINATES   = 53,                // set unit coordinates as dest, only 16 target B imlemented
     TARGET_LARGE_FRONTAL_CONE          = 54,
@@ -1197,8 +1198,8 @@ enum GameObjectFlags
     GO_FLAG_TRIGGERED       = 0x00000040,                   //typically, summoned objects. Triggered by spell or other events
     GO_FLAG_UNK_8           = 0x00000080,
     GO_FLAG_UNK_9           = 0x00000100,                   //? Seen on type 33, possible meaning "destruct in progress"
-    GO_FLAG_UNK_10          = 0x00000200,                   //? Seen on type 33
-    GO_FLAG_UNK_11          = 0x00000400                    //? Seen on type 33, possibly meaning "destructed"
+    GO_FLAG_DAMAGED         = 0x00000200,                   //? Seen on type 33
+    GO_FLAG_DESTROYED       = 0x00000400                    //? Seen on type 33, possibly meaning "destructed"
 };
 
 enum TextEmotes
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index 0c80e73..6c9552f 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1429,9 +1429,38 @@ void Spell::SetTargetMap(uint32 effIndex, uint32 targetMode, UnitList& targetUni
         case TARGET_SELF:
         case TARGET_SELF2:
         case TARGET_AREAEFFECT_CUSTOM:
-        case TARGET_AREAEFFECT_CUSTOM_2:
             targetUnitMap.push_back(m_caster);
             break;
+        case TARGET_AREAEFFECT_CUSTOM_2:
+        {
+            float x, y, z;
+            if(targetMode == TARGET_OBJECT_AREA_SRC)
+            {
+                if(m_targets.HasSrc())
+                {
+                    x = m_targets.m_srcX;
+                    y = m_targets.m_srcY;
+                    z = m_targets.m_srcZ;
+                }
+                else
+                    break;
+            }
+            else if(m_targets.HasDst())
+            {
+                x = m_targets.m_destX;
+                y = m_targets.m_destY;
+                z = m_targets.m_destZ;
+            }
+            else
+                break;
+
+            MaNGOS::GameObjectInRangeCheck check(x, y, z, radius + 15);
+            std::list<GameObject*> goList;
+            MaNGOS::GameObjectListSearcher<MaNGOS::GameObjectInRangeCheck> searcher(m_caster, goList, check);
+            m_caster->GetMap()->VisitGrid(x, y, radius, searcher);
+            for(std::list<GameObject*>::iterator itr = goList.begin(); itr != goList.end(); ++itr)
+                AddGOTarget(*itr, effIndex);
+		}
         case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA:
         {
             m_targets.m_targetMask = 0;
diff --git a/src/game/Spell.h b/src/game/Spell.h
index 00878b4..058c8a9 100644
--- a/src/game/Spell.h
+++ b/src/game/Spell.h
@@ -164,6 +164,8 @@ class SpellCastTargets
         }
 
         bool IsEmpty() const { return m_GOTargetGUID==0 && m_unitTargetGUID==0 && m_itemTarget==0 && m_CorpseTargetGUID==0; }
+        bool HasSrc() const { return m_targetMask & TARGET_FLAG_SOURCE_LOCATION; }
+        bool HasDst() const { return m_targetMask & TARGET_FLAG_DEST_LOCATION; }
 
         void Update(Unit* caster);
 
@@ -323,6 +325,8 @@ class Spell
         void EffectKillCreditPersonal(uint32 i);
         void EffectKillCredit(uint32 i);
         void EffectQuestFail(uint32 i);
+        void EffectWMODamage(uint32 i);
+        void EffectWMORepair(uint32 i);
         void EffectActivateRune(uint32 i);
         void EffectTitanGrip(uint32 i);
         void EffectEnchantItemPrismatic(uint32 i);
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 5e18c1b..6ad6932 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -144,8 +144,8 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS]=
     &Spell::EffectStuck,                                    // 84 SPELL_EFFECT_STUCK
     &Spell::EffectSummonPlayer,                             // 85 SPELL_EFFECT_SUMMON_PLAYER
     &Spell::EffectActivateObject,                           // 86 SPELL_EFFECT_ACTIVATE_OBJECT
-    &Spell::EffectUnused,                                   // 87 SPELL_EFFECT_WMO_DAMAGE
-    &Spell::EffectUnused,                                   // 88 SPELL_EFFECT_WMO_REPAIR
+    &Spell::EffectWMODamage,                                // 87 SPELL_EFFECT_WMO_DAMAGE
+    &Spell::EffectWMORepair,                                // 88 SPELL_EFFECT_WMO_REPAIR
     &Spell::EffectUnused,                                   // 89 SPELL_EFFECT_WMO_CHANGE
     &Spell::EffectKillCreditPersonal,                       // 90 SPELL_EFFECT_KILL_CREDIT              Kill credit but only for single person
     &Spell::EffectUnused,                                   // 91 SPELL_EFFECT_THREAT_ALL               one spell: zzOLDBrainwash
@@ -3158,7 +3158,7 @@ void Spell::EffectOpenLock(uint32 effIndex)
             if (BattleGround *bg = player->GetBattleGround())
             {
                 // check if it's correct bg
-                if (bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_AV)
+                if (bg->GetTypeID() == BATTLEGROUND_AB || bg->GetTypeID() == BATTLEGROUND_AV || bg->GetTypeID() == BATTLEGROUND_SA)
                     bg->EventPlayerClickedOnFlag(player, gameObjTarget);
                 return;
             }
@@ -6965,3 +6965,15 @@ void Spell::EffectPlayMusic(uint32 i)
     data << uint32(soundid);
     ((Player*)unitTarget)->GetSession()->SendPacket(&data);
 }
+
+void Spell::EffectWMODamage(uint32 /*i*/)
+{
+    if(gameObjTarget && gameObjTarget->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
+        gameObjTarget->TakenDamage((uint32)damage,m_caster);
+}
+
+void Spell::EffectWMORepair(uint32 /*i*/)
+{
+    if(gameObjTarget && gameObjTarget->GetGoType() == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING)
+        gameObjTarget->Rebuild(m_caster);
+}
Патч на ядро,
автор: Rage Hunter.
Однако надо его чуть чуть переписать, ибо 9245 коммит
Цитата:
[9245] Remove CellLock class and all cell-level thread locking.
* CellLock was just a 'proxy' between Cell and CellPair and in some cases carried redundant data.
Gen1us2k вне форума