Ejemplo n.º 1
0
        void InitOrbit(AreaTriggerOrbitInfo cmi, uint timeToTarget)
        {
            // Circular movement requires either a center position or an attached unit
            Cypher.Assert(cmi.Center.HasValue || cmi.PathTarget.HasValue);

            // should be sent in object create packets only
            DoWithSuppressingObjectUpdates(() =>
            {
                SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTarget), timeToTarget);
                m_areaTriggerData.ClearChanged(m_areaTriggerData.TimeToTarget);
            });

            _orbitInfo.Set(cmi);

            _orbitInfo.Value.TimeToTarget           = timeToTarget;
            _orbitInfo.Value.ElapsedTimeForMovement = 0;

            if (IsInWorld)
            {
                AreaTriggerRePath reshape = new();
                reshape.TriggerGUID      = GetGUID();
                reshape.AreaTriggerOrbit = _orbitInfo;

                SendMessageToSet(reshape, true);
            }
        }
Ejemplo n.º 2
0
        Position CalculateOrbitPosition()
        {
            Position centerPos = GetOrbitCenterPosition();

            if (centerPos == null)
            {
                return(GetPosition());
            }

            AreaTriggerOrbitInfo cmi = _orbitInfo.Value;

            // AreaTrigger make exactly "Duration / TimeToTarget" loops during his life time
            float pathProgress = (float)cmi.ElapsedTimeForMovement / cmi.TimeToTarget;

            // We already made one circle and can't loop
            if (!cmi.CanLoop)
            {
                pathProgress = Math.Min(1.0f, pathProgress);
            }

            float radius = cmi.Radius;

            if (MathFunctions.fuzzyNe(cmi.BlendFromRadius, radius))
            {
                float blendCurve = (cmi.BlendFromRadius - radius) / radius;
                // 4.f Defines four quarters
                blendCurve = MathFunctions.RoundToInterval(ref blendCurve, 1.0f, 4.0f) / 4.0f;
                float blendProgress = Math.Min(1.0f, pathProgress / blendCurve);
                radius = MathFunctions.lerp(cmi.BlendFromRadius, cmi.Radius, blendProgress);
            }

            // Adapt Path progress depending of circle direction
            if (!cmi.CounterClockwise)
            {
                pathProgress *= -1;
            }

            float angle = cmi.InitialAngle + 2.0f * (float)Math.PI * pathProgress;
            float x     = centerPos.GetPositionX() + (radius * (float)Math.Cos(angle));
            float y     = centerPos.GetPositionY() + (radius * (float)Math.Sin(angle));
            float z     = centerPos.GetPositionZ() + cmi.ZOffset;

            return(new Position(x, y, z, angle));
        }
Ejemplo n.º 3
0
        bool Create(uint spellMiscId, Unit caster, Unit target, SpellInfo spell, Position pos, int duration, SpellCastVisualField spellVisual, ObjectGuid castId, AuraEffect aurEff)
        {
            _targetGuid = target ? target.GetGUID() : ObjectGuid.Empty;
            _aurEff     = aurEff;

            SetMap(caster.GetMap());
            Relocate(pos);
            if (!IsPositionValid())
            {
                Log.outError(LogFilter.AreaTrigger, $"AreaTrigger (spell {spell.Id}) not created. Invalid coordinates (X: {GetPositionX()} Y: {GetPositionY()})");
                return(false);
            }

            _areaTriggerMiscTemplate = Global.AreaTriggerDataStorage.GetAreaTriggerMiscTemplate(spellMiscId);
            if (_areaTriggerMiscTemplate == null)
            {
                Log.outError(LogFilter.AreaTrigger, "AreaTrigger (spellMiscId {0}) not created. Invalid areatrigger miscid ({1})", spellMiscId, spellMiscId);
                return(false);
            }

            _areaTriggerTemplate = _areaTriggerMiscTemplate.Template;

            _Create(ObjectGuid.Create(HighGuid.AreaTrigger, GetMapId(), GetTemplate().Id.Id, caster.GetMap().GenerateLowGuid(HighGuid.AreaTrigger)));

            SetEntry(GetTemplate().Id.Id);
            SetDuration(duration);

            SetObjectScale(1.0f);

            SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.Caster), caster.GetGUID());
            SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.CreatingEffectGUID), castId);

            SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.SpellID), spell.Id);
            SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.SpellForVisuals), spell.Id);

            SpellCastVisualField spellCastVisual = m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.SpellVisual);

            SetUpdateFieldValue(ref spellCastVisual.SpellXSpellVisualID, spellVisual.SpellXSpellVisualID);
            SetUpdateFieldValue(ref spellCastVisual.ScriptVisualID, spellVisual.ScriptVisualID);

            SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.TimeToTargetScale), GetMiscTemplate().TimeToTargetScale != 0 ? GetMiscTemplate().TimeToTargetScale : m_areaTriggerData.Duration);
            SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.BoundsRadius2D), GetTemplate().MaxSearchRadius);
            SetUpdateFieldValue(m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.DecalPropertiesID), GetMiscTemplate().DecalPropertiesId);

            ScaleCurve extraScaleCurve = m_values.ModifyValue(m_areaTriggerData).ModifyValue(m_areaTriggerData.ExtraScaleCurve);

            if (GetMiscTemplate().ExtraScale.Structured.StartTimeOffset != 0)
            {
                SetUpdateFieldValue(extraScaleCurve.ModifyValue(extraScaleCurve.StartTimeOffset), GetMiscTemplate().ExtraScale.Structured.StartTimeOffset);
            }
            if (GetMiscTemplate().ExtraScale.Structured.X != 0 || GetMiscTemplate().ExtraScale.Structured.Y != 0)
            {
                Vector2 point = new(GetMiscTemplate().ExtraScale.Structured.X, GetMiscTemplate().ExtraScale.Structured.Y);
                SetUpdateFieldValue(ref extraScaleCurve.ModifyValue(extraScaleCurve.Points, 0), point);
            }
            if (GetMiscTemplate().ExtraScale.Structured.Z != 0 || GetMiscTemplate().ExtraScale.Structured.W != 0)
            {
                Vector2 point = new(GetMiscTemplate().ExtraScale.Structured.Z, GetMiscTemplate().ExtraScale.Structured.W);
                SetUpdateFieldValue(ref extraScaleCurve.ModifyValue(extraScaleCurve.Points, 1), point);
            }
            unsafe
            {
                if (GetMiscTemplate().ExtraScale.Raw.Data[5] != 0)
                {
                    SetUpdateFieldValue(extraScaleCurve.ModifyValue(extraScaleCurve.ParameterCurve), GetMiscTemplate().ExtraScale.Raw.Data[5]);
                }
                if (GetMiscTemplate().ExtraScale.Structured.OverrideActive != 0)
                {
                    SetUpdateFieldValue(extraScaleCurve.ModifyValue(extraScaleCurve.OverrideActive), GetMiscTemplate().ExtraScale.Structured.OverrideActive != 0 ? true : false);
                }
            }


            PhasingHandler.InheritPhaseShift(this, caster);

            if (target && GetTemplate().HasFlag(AreaTriggerFlags.HasAttached))
            {
                m_movementInfo.transport.guid = target.GetGUID();
            }

            UpdateShape();

            uint timeToTarget = GetMiscTemplate().TimeToTarget != 0 ? GetMiscTemplate().TimeToTarget : m_areaTriggerData.Duration;

            if (GetTemplate().HasFlag(AreaTriggerFlags.HasCircularMovement))
            {
                AreaTriggerOrbitInfo cmi = GetMiscTemplate().OrbitInfo;
                if (target && GetTemplate().HasFlag(AreaTriggerFlags.HasAttached))
                {
                    cmi.PathTarget.Set(target.GetGUID());
                }
                else
                {
                    cmi.Center.Set(new Vector3(pos.posX, pos.posY, pos.posZ));
                }

                InitOrbit(cmi, timeToTarget);
            }
            else if (GetMiscTemplate().HasSplines())
            {
                InitSplineOffsets(GetMiscTemplate().SplinePoints, timeToTarget);
            }

            // movement on transport of areatriggers on unit is handled by themself
            Transport transport = m_movementInfo.transport.guid.IsEmpty() ? caster.GetTransport() : null;

            if (transport)
            {
                float x, y, z, o;
                pos.GetPosition(out x, out y, out z, out o);
                transport.CalculatePassengerOffset(ref x, ref y, ref z, ref o);
                m_movementInfo.transport.pos.Relocate(x, y, z, o);

                // This object must be added to transport before adding to map for the client to properly display it
                transport.AddPassenger(this);
            }

            AI_Initialize();

            // Relocate areatriggers with circular movement again
            if (HasOrbit())
            {
                Relocate(CalculateOrbitPosition());
            }

            if (!GetMap().AddToMap(this))
            {         // Returning false will cause the object to be deleted - remove from transport
                if (transport)
                {
                    transport.RemovePassenger(this);
                }
                return(false);
            }

            caster._RegisterAreaTrigger(this);

            _ai.OnCreate();

            return(true);
        }