root/trunk/src/game/DynamicObject.cpp @ 28

Revision 2, 5.0 kB (checked in by yumileroy, 17 years ago)

[svn] * Proper SVN structure

Original author: Neo2003
Date: 2008-10-02 16:23:55-05:00

Line 
1/*
2 * Copyright (C) 2005-2008 MaNGOS <http://www.mangosproject.org/>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19#include "Common.h"
20#include "GameObject.h"
21#include "UpdateMask.h"
22#include "Opcodes.h"
23#include "WorldPacket.h"
24#include "WorldSession.h"
25#include "World.h"
26#include "ObjectAccessor.h"
27#include "Database/DatabaseEnv.h"
28#include "SpellAuras.h"
29#include "MapManager.h"
30#include "GridNotifiers.h"
31#include "CellImpl.h"
32#include "GridNotifiersImpl.h"
33
34DynamicObject::DynamicObject() : WorldObject()
35{
36    m_objectType |= TYPEMASK_DYNAMICOBJECT;
37    m_objectTypeId = TYPEID_DYNAMICOBJECT;
38                                                            // 2.3.2 - 0x58
39    m_updateFlag = (UPDATEFLAG_LOWGUID | UPDATEFLAG_HIGHGUID | UPDATEFLAG_HASPOSITION);
40
41    m_valuesCount = DYNAMICOBJECT_END;
42}
43
44void DynamicObject::AddToWorld()
45{
46    ///- Register the dynamicObject for guid lookup
47    if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this);
48    Object::AddToWorld();
49}
50
51void DynamicObject::RemoveFromWorld()
52{
53    ///- Remove the dynamicObject from the accessor
54    if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this);
55    Object::RemoveFromWorld();
56}
57
58bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32 effIndex, float x, float y, float z, int32 duration, float radius )
59{
60    SetInstanceId(caster->GetInstanceId());
61
62    WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId());
63    Relocate(x,y,z,0);
64
65    if(!IsPositionValid())
66    {
67        sLog.outError("ERROR: DynamicObject (spell %u eff %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,effIndex,GetPositionX(),GetPositionY());
68        return false;
69    }
70
71    SetUInt32Value( OBJECT_FIELD_ENTRY, spellId );
72    SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
73    SetUInt64Value( DYNAMICOBJECT_CASTER, caster->GetGUID() );
74    SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 );
75    SetUInt32Value( DYNAMICOBJECT_SPELLID, spellId );
76    SetFloatValue( DYNAMICOBJECT_RADIUS, radius);
77    SetFloatValue( DYNAMICOBJECT_POS_X, x );
78    SetFloatValue( DYNAMICOBJECT_POS_Y, y );
79    SetFloatValue( DYNAMICOBJECT_POS_Z, z );
80    SetUInt32Value( DYNAMICOBJECT_CASTTIME, getMSTime() );  // new 2.4.0
81
82    m_aliveDuration = duration;
83    m_radius = radius;
84    m_effIndex = effIndex;
85    m_spellId = spellId;
86    m_casterGuid = caster->GetGUID();
87    return true;
88}
89
90Unit* DynamicObject::GetCaster() const
91{
92    // can be not found in some cases
93    return ObjectAccessor::GetUnit(*this,m_casterGuid);
94}
95
96void DynamicObject::Update(uint32 p_time)
97{
98    // caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor
99    Unit* caster = GetCaster();
100    if(!caster)
101    {
102        Delete();
103        return;
104    }
105
106    bool deleteThis = false;
107
108    if(m_aliveDuration > int32(p_time))
109        m_aliveDuration -= p_time;
110    else
111        deleteThis = true;
112
113    // TODO: make a timer and update this in larger intervals
114    CellPair p(MaNGOS::ComputeCellPair(GetPositionX(), GetPositionY()));
115    Cell cell(p);
116    cell.data.Part.reserved = ALL_DISTRICT;
117    cell.SetNoCreate();
118
119    MaNGOS::DynamicObjectUpdater notifier(*this,caster);
120
121    TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, WorldTypeMapContainer > world_object_notifier(notifier);
122    TypeContainerVisitor<MaNGOS::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier);
123
124    CellLock<GridReadGuard> cell_lock(cell, p);
125    cell_lock->Visit(cell_lock, world_object_notifier, *MapManager::Instance().GetMap(GetMapId(), this));
126    cell_lock->Visit(cell_lock, grid_object_notifier,  *MapManager::Instance().GetMap(GetMapId(), this));
127
128    if(deleteThis)
129    {
130        caster->RemoveDynObjectWithGUID(GetGUID());
131        Delete();
132    }
133}
134
135void DynamicObject::Delete()
136{
137    SendObjectDeSpawnAnim(GetGUID());
138    AddObjectToRemoveList();
139}
140
141void DynamicObject::Delay(int32 delaytime)
142{
143    m_aliveDuration -= delaytime;
144    for(AffectedSet::iterator iunit= m_affected.begin();iunit != m_affected.end();++iunit)
145        if (*iunit)
146            (*iunit)->DelayAura(m_spellId, m_effIndex, delaytime);
147}
148
149bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
150{
151    return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f));
152}
Note: See TracBrowser for help on using the browser.