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

Revision 120, 5.1 kB (checked in by yumileroy, 17 years ago)

[svn] * Allow WorldObjects? to keep the grid active, and prevent it from being unloaded. This can be done through calling WorldObject::setActive(bool) from the scripting library. Note that entire instances are still unloaded if no player is present on that map to save resources. This behavior can be changed if the need arises.

Original author: w12x
Date: 2008-10-27 08:41:55-05:00

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