aboutsummaryrefslogtreecommitdiff
path: root/src/game/DynamicObject.cpp
diff options
context:
space:
mode:
authorQAston <none@none>2010-01-10 01:23:15 +0100
committerQAston <none@none>2010-01-10 01:23:15 +0100
commit8e9d2cdf01929f513e37eccbfdea952aa04e78f6 (patch)
tree54d298a9e7f5b84bd230bf340d76180116008496 /src/game/DynamicObject.cpp
parenta0f7762cab9b759b7d3e7dc25a447b5e43f2048b (diff)
Update aura system:
* Change system logic - unify Auras, AreaAuras and PersistentAreaAuras: * Aura has now its owner - which is the WorldObject, which applies aura (creates AuraApplication object) dependant on aura radius, and effect type * Owner can be Dynobj (DynObjAura class) for PersistentAreaAuras, or Unit (UnitAura class) for Area and nonArea auras * Aura data is shared for all units which have AuraApplication of the Aura * Because of that AuraEffect handlers , and periodic tick functions can't modify AuraEffect object (they are const now) * Remove spell source and AreaAuraEffect classes * Add AuraEffect::UpdatePeriodic function, to allow periodic aura object modification (target independant) * Add AuraEffect::CalculateAmount and AuraEffect::CalculateSpellMod function, to allow non-default amount calculation * AreaAura updates are done in owner _UpdateSpells cycle * Since now you don't need to wait an aura update cycle to get area aura applied on it's correct target list * And you can access area aura target list * Add basic support for aura amount recalculation * Save recalculation state and base amount of auras to db * Add AuraEffect::CalculatePeriodic function to determine if aura is periodic, and to set correct tick number after aura is loaded from db * Add ChangeAmount function in addition to SetAmount function, to allow easy reapplication of AuraEffect handlers on all targets * Sort aura effect handlers in SpellAuras.cpp and .h by their use * Add check for already existing aura of that type to some AuraEffect handlers, to prevent incorrect effect removal * SPELL_AURA_CONVERT_RUNE and MOD_POWER_REGEN and MOD_REGEN hacky handlers are now implemented correctly * Send aura application client update only once per unit update - prevent unnecesary packet spam * Fix ByteBuffer::appendPackGUID function - it added additionall 0s at the end of the packet * Fix memory leak at player creation (not deleted auras) * Updated some naming conventions (too many to mention) * Added Unit::GetAuraOfRankedSpell() function * Remove procflags on aura remove, use Aura::HandleAuraSpecificMods instead * Added functions to maintain owned auras (GetOwnedAuras, GetOwnedAura, RemoveOwnedAura, etc) * Implement AURA_INTERRUPT_FLAG_LANDING * Implement EffectPlayerNotification (thanks to Spp) * Remove wrong aura 304 handler * Add better handler for death runes * Remove unnecesary variables from DynamicObject class, and cleanup related code, link dynobj duration with aura * Add GetAuraEffectTriggerTarget function in CreatureAi for special target selection for periodic trigger auras used in a script * Add many assert() procection from idiots using some functions in wrong way * I am to lazy to write here anything more Thanks to Visagalis for testing this patch PS: Do not make patches like this, please --HG-- branch : trunk
Diffstat (limited to 'src/game/DynamicObject.cpp')
-rw-r--r--src/game/DynamicObject.cpp93
1 files changed, 46 insertions, 47 deletions
diff --git a/src/game/DynamicObject.cpp b/src/game/DynamicObject.cpp
index 1cd85fa0946..6105ece654e 100644
--- a/src/game/DynamicObject.cpp
+++ b/src/game/DynamicObject.cpp
@@ -36,6 +36,9 @@ DynamicObject::DynamicObject() : WorldObject()
m_updateFlag = (UPDATEFLAG_HIGHGUID | UPDATEFLAG_HAS_POSITION | UPDATEFLAG_POSITION);
m_valuesCount = DYNAMICOBJECT_END;
+
+ m_aura = 0;
+ m_duration = 0;
}
void DynamicObject::AddToWorld()
@@ -70,13 +73,13 @@ void DynamicObject::RemoveFromWorld()
}
}
-bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32 effMask, const Position &pos, int32 duration, float radius, bool active)
+bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, const Position &pos, float radius, bool active)
{
SetMap(caster->GetMap());
Relocate(pos);
if(!IsPositionValid())
{
- sLog.outError("DynamicObject (spell %u eff %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,effMask,GetPositionX(),GetPositionY());
+ sLog.outError("DynamicObject (spell %u) not created. Suggested coordinates isn't valid (X: %f Y: %f)",spellId,GetPositionX(),GetPositionY());
return false;
}
@@ -85,17 +88,11 @@ bool DynamicObject::Create(uint32 guidlow, Unit *caster, uint32 spellId, uint32
SetEntry(spellId);
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
SetUInt64Value( DYNAMICOBJECT_CASTER, caster->GetGUID() );
- SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 );
+ SetUInt32Value( DYNAMICOBJECT_BYTES, 0x00000001 ); // effectMask?
SetUInt32Value( DYNAMICOBJECT_SPELLID, spellId );
- SetFloatValue( DYNAMICOBJECT_RADIUS, radius);
+ SetFloatValue( DYNAMICOBJECT_RADIUS, radius );
SetUInt32Value( DYNAMICOBJECT_CASTTIME, getMSTime() ); // new 2.4.0
- m_aliveDuration = duration;
- m_radius = radius;
- m_effMask = effMask;
- m_spellId = spellId;
- m_updateTimer = 0;
-
m_isWorldObject = active;
return true;
}
@@ -116,45 +113,25 @@ void DynamicObject::Update(uint32 p_time)
return;
}
- bool deleteThis = false;
+ bool expired = false;
- if(m_aliveDuration > int32(p_time))
- m_aliveDuration -= p_time;
- else
- deleteThis = true;
-
- /*
- // have radius and work as persistent effect
- if(m_radius)
+ if (m_aura)
{
- // TODO: make a timer and update this in larger intervals
- CellPair p(Trinity::ComputeCellPair(GetPositionX(), GetPositionY()));
- Cell cell(p);
- cell.data.Part.reserved = ALL_DISTRICT;
- cell.SetNoCreate();
-
- Trinity::DynamicObjectUpdater notifier(*this, caster);
+ if (!m_aura->IsRemoved())
+ m_aura->UpdateOwner(p_time, this);
- TypeContainerVisitor<Trinity::DynamicObjectUpdater, WorldTypeMapContainer > world_object_notifier(notifier);
- TypeContainerVisitor<Trinity::DynamicObjectUpdater, GridTypeMapContainer > grid_object_notifier(notifier);
-
- CellLock<GridReadGuard> cell_lock(cell, p);
- cell_lock->Visit(cell_lock, world_object_notifier, *GetMap(), *this, m_radius);
- cell_lock->Visit(cell_lock, grid_object_notifier, *GetMap(), *this, m_radius);
+ if (m_aura->IsRemoved() || m_aura->IsExpired())
+ expired = true;
}
- */
-
- if (m_effMask)
+ else
{
- if (m_updateTimer < p_time)
- {
- Trinity::DynamicObjectUpdater notifier(*this,caster);
- VisitNearbyObject(GetRadius(), notifier);
- m_updateTimer = 500; // is this official-like?
- } else m_updateTimer -= p_time;
+ if(GetDuration() > int32(p_time))
+ m_duration -= p_time;
+ else
+ expired = true;
}
- if (deleteThis)
+ if (expired)
{
caster->RemoveDynObjectWithGUID(GetGUID());
Delete();
@@ -163,21 +140,43 @@ void DynamicObject::Update(uint32 p_time)
void DynamicObject::Delete()
{
+ if (m_aura)
+ {
+ // dynObj may be removed in Aura::Remove - we cannot delete there
+ // so recheck aura here
+ if (!m_aura->IsRemoved())
+ m_aura->_Remove(AURA_REMOVE_BY_DEFAULT);
+ delete m_aura;
+ m_aura = NULL;
+ }
SendObjectDeSpawnAnim(GetGUID());
RemoveFromWorld();
AddObjectToRemoveList();
}
+int32 DynamicObject::GetDuration() const
+{
+ if (!m_aura)
+ return m_duration;
+ else
+ return m_aura->GetDuration();
+}
+
+void DynamicObject::SetDuration(int32 newDuration)
+{
+ if (!m_aura)
+ m_duration = newDuration;
+ else
+ m_aura->SetDuration(newDuration);
+}
+
void DynamicObject::Delay(int32 delaytime)
{
- m_aliveDuration -= delaytime;
- for (AffectedSet::iterator iunit = m_affected.begin(); iunit != m_affected.end(); ++iunit)
- if (*iunit)
- (*iunit)->DelayAura(m_spellId, GetCaster()->GetGUID(), delaytime);
+ SetDuration(GetDuration() - delaytime);
}
bool DynamicObject::isVisibleForInState(Player const* u, bool inVisibleList) const
{
return IsInWorld() && u->IsInWorld()
&& (IsWithinDistInMap(u->m_seer,World::GetMaxVisibleDistanceForObject()+(inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false));
-}
+} \ No newline at end of file