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 | |
---|
36 | DynamicObject::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 | |
---|
46 | void DynamicObject::AddToWorld() |
---|
47 | { |
---|
48 | ///- Register the dynamicObject for guid lookup |
---|
49 | if(!IsInWorld()) ObjectAccessor::Instance().AddObject(this); |
---|
50 | Object::AddToWorld(); |
---|
51 | } |
---|
52 | |
---|
53 | void DynamicObject::RemoveFromWorld() |
---|
54 | { |
---|
55 | ///- Remove the dynamicObject from the accessor |
---|
56 | if(IsInWorld()) ObjectAccessor::Instance().RemoveObject(this); |
---|
57 | Object::RemoveFromWorld(); |
---|
58 | } |
---|
59 | |
---|
60 | bool 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 | |
---|
92 | Unit* DynamicObject::GetCaster() const |
---|
93 | { |
---|
94 | // can be not found in some cases |
---|
95 | return ObjectAccessor::GetUnit(*this,m_casterGuid); |
---|
96 | } |
---|
97 | |
---|
98 | void 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 | |
---|
137 | void DynamicObject::Delete() |
---|
138 | { |
---|
139 | SendObjectDeSpawnAnim(GetGUID()); |
---|
140 | AddObjectToRemoveList(); |
---|
141 | } |
---|
142 | |
---|
143 | void 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 | |
---|
151 | bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const |
---|
152 | { |
---|
153 | return IsInWorld() && u->IsInWorld() && IsWithinDistInMap(u,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f)); |
---|
154 | } |
---|