diff options
author | QAston <none@none> | 2010-01-10 01:23:15 +0100 |
---|---|---|
committer | QAston <none@none> | 2010-01-10 01:23:15 +0100 |
commit | 8e9d2cdf01929f513e37eccbfdea952aa04e78f6 (patch) | |
tree | 54d298a9e7f5b84bd230bf340d76180116008496 /src/game/DynamicObject.cpp | |
parent | a0f7762cab9b759b7d3e7dc25a447b5e43f2048b (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.cpp | 93 |
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 |