void DynamicObject::Update(uint32 /*update_diff*/, uint32 p_time) { Unit* caster = NULL; if (GetType() == DYNAMIC_OBJECT_RAID_MARKER) { Group* group = sObjectMgr.GetGroup(GetCasterGuid()); if (!group || !group->HasRaidMarker(GetObjectGuid())) { Delete(); return; } } else { caster = GetCaster(); // caster can be not in world at time dynamic object update, but dynamic object not yet deleted in Unit destructor if (!caster) { Delete(); return; } } bool deleteThis = false; if (m_aliveDuration > int32(p_time)) m_aliveDuration -= p_time; else deleteThis = true; // have radius and work as persistent effect if (m_radius && caster) { // TODO: make a timer and update this in larger intervals MaNGOS::DynamicObjectUpdater notifier(*this, caster, m_positive); Cell::VisitAllObjects(this, notifier, m_radius); } if (deleteThis) { DEBUG_LOG("DynObject %s type %u removed from caster %s", GetGuidStr().c_str(), GetType(), caster->GetGuidStr().c_str()); if (GetType() == DYNAMIC_OBJECT_RAID_MARKER) { if (Group* group = sObjectMgr.GetGroup(GetCasterGuid())) group->ClearRaidMarker(GetObjectGuid()); } else caster->RemoveDynObjectWithGuid(GetObjectGuid()); Delete(); } }
void DynamicObject::Delay(int32 delaytime) { m_aliveDuration -= delaytime; for (GuidSet::iterator iter = m_affected.begin(); iter != m_affected.end();) { Unit* target = GetMap()->GetUnit((*iter)); if (target) { SpellAuraHolderPtr holder = target->GetSpellAuraHolder(m_spellId, GetCasterGuid()); if (!holder || holder->IsDeleted()) { ++iter; continue; } bool foundAura = false; for (int32 i = m_effIndex + 1; i < MAX_EFFECT_INDEX; ++i) { SpellEffectEntry const* effectEntry = holder->GetSpellProto()->GetSpellEffect(SpellEffectIndex(i)); if(!effectEntry) continue; if ((effectEntry->Effect == SPELL_EFFECT_PERSISTENT_AREA_AURA || effectEntry->Effect == SPELL_EFFECT_ADD_FARSIGHT) && holder->GetAuraByEffectIndex(SpellEffectIndex(i))) { foundAura = true; break; } } if (foundAura) { ++iter; continue; } target->DelaySpellAuraHolder(m_spellId, delaytime, GetCasterGuid()); ++iter; } else m_affected.erase(iter++); } }
bool DynamicObject::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const { if (!IsInWorld() || !u->IsInWorld()) return false; // always seen by owner if (GetCasterGuid() == u->GetObjectGuid()) return true; // normal case return IsWithinDistInMap(viewPoint, GetMap()->GetVisibilityDistance() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false); }
bool DynamicObject::isVisibleForInState(Player const* u, WorldObject const* viewPoint, bool inVisibleList) const { if (!IsInWorld() || !u->IsInWorld()) return false; // always seen by owner if (GetCasterGuid() == u->GetObjectGuid()) return true; if (GetType() == DYNAMIC_OBJECT_RAID_MARKER) { Group const* group = u->GetGroup(); if (!group) return false; if (GetCasterGuid() != group->GetObjectGuid()) return false; } // normal case return IsWithinDistInMap(viewPoint, GetMap()->GetVisibilityDistance() + (inVisibleList ? World::GetVisibleObjectGreyDistance() : 0.0f), false); }
void DynamicObject::Delay(int32 delaytime) { m_aliveDuration -= delaytime; for(AffectedSet::iterator iter = m_affected.begin(); iter != m_affected.end(); ) { Unit *target = GetMap()->GetUnit((*iter)); if (target) { SpellAuraHolder *holder = target->GetSpellAuraHolder(m_spellId, GetCasterGuid()); if (!holder) { ++iter; continue; } bool foundAura = false; for (int32 i = m_effIndex + 1; i < MAX_EFFECT_INDEX; ++i) { if ((holder->GetSpellProto()->Effect[i] == SPELL_EFFECT_PERSISTENT_AREA_AURA || holder->GetSpellProto()->Effect[i] == SPELL_EFFECT_ADD_FARSIGHT) && holder->m_auras[i]) { foundAura = true; break; } } if (foundAura) { ++iter; continue; } target->DelaySpellAuraHolder(m_spellId, delaytime, GetCasterGuid()); ++iter; } else m_affected.erase(iter++); } }
Unit* DynamicObject::GetCaster() const { // can be not found in some cases return ObjectAccessor::GetUnit(*this, GetCasterGuid()); }
void AreaTrigger::UndoActions(Unit* unit) { for (AreaTriggerAction const& action : GetTemplate()->Actions) if (action.ActionType == AREATRIGGER_ACTION_CAST || action.ActionType == AREATRIGGER_ACTION_ADDAURA) unit->RemoveAurasDueToSpell(action.Param, GetCasterGuid()); }
Unit* AreaTrigger::GetCaster() const { return ObjectAccessor::GetUnit(*this, GetCasterGuid()); }