Ejemplo n.º 1
0
        public override void EventFired(object sender, Event evt)
        {
            PulseEmitterComponent pem;

            if (evt is PulseEvent pe)
            {
                foreach (PulsePushable pp in WatchedComponents.Where(c => c is PulsePushable))
                {
                    if (!pp.Owner.Active)
                    {
                        continue;
                    }
                    if (pp.Owner == evt.Sender.Owner)
                    {
                        continue;
                    }
                    if (!pp.Owner.Components.Has <Spatial>() || !pp.Owner.Components.Has <Physical>())
                    {
                        continue;
                    }
                    Physical ph = pp.Owner.Components.Get <Physical>();

                    Vector2D center = pp.Owner.Components.Has <SoftBody>() ? pp.Owner.Components.Get <SoftBody>().Bounds.Offset(ph.Position).Center : ph.Position;

                    double distance = (center - pe.Source).Magnitude;

                    if (distance > pe.Reach)
                    {
                        continue;
                    }

                    if (pe.Direction.Magnitude == 0 || GeneralUtil.SubtractAngles((center - pe.Source).Angle, pe.Direction.Angle) <= Math.Atan(1 / pe.Direction.Magnitude))
                    {
                        double mass = 1;
                        if (pp.Owner.Components.Has <SoftBody>())
                        {
                            mass = pp.Owner.Components.Get <SoftBody>().Mass;
                        }
                        double factor = 1 - (distance / pe.Reach);
                        ph.Velocity += ((center - pe.Source).Normalize() * (factor * pe.Strength) / mass);

                        if (pp.Owner.Components.Get <ProjectileComponent>() is ProjectileComponent projectile && projectile.Deflectable && pp.Owner.Components.Get <DamageOnContactComponent>() is DamageOnContactComponent damager)
                        {
                            if (pe.Sender != null)
                            {
                                projectile.Thrower = pe.Sender.Owner.Id;
                                if (pe.Sender.Owner.Components.Has <PlayerComponent>())
                                {
                                    damager.Filter = DamageFilter.DamageEnemies;
                                }
                                else if (pe.Sender.Owner.Components.Has <EnemyComponent>())
                                {
                                    damager.Filter = DamageFilter.DamageAllies;
                                }
                            }
                        }
                    }
                }

                if (pe.Direction.Magnitude > 0)
                {
                    List <Entity> hit     = new List <Entity>();
                    List <Entity> damaged = new List <Entity>();

                    for (int i = -1; i <= 1; i++)
                    {
                        RaycastEvent raycast = new RaycastEvent(evt.Sender, new FreeVector2D(pe.Source, pe.Source + pe.Direction.Rotate(i * (Math.PI / 4)) * pe.Reach));
                        Owner.Events.InvokeEvent(raycast);
                        if (raycast.Intersected != null)
                        {
                            foreach (RaycastIntersection intersection in raycast.Intersected)
                            {
                                if (intersection.Component.Owner != pe.Sender.Owner &&
                                    intersection.Component.Owner.Components.Has <PulseReceiverPhysical>() &&
                                    !hit.Contains(intersection.Component.Owner))
                                {
                                    hit.Add(intersection.Component.Owner);
                                }
                                else if (intersection.Component.Owner != pe.Sender.Owner &&
                                         intersection.Component.Owner.Components.Has <PulseDamaged>() &&
                                         !damaged.Contains(intersection.Component.Owner))
                                {
                                    damaged.Add(intersection.Component.Owner);
                                }
                            }
                        }
                    }

                    hit.ForEach(e => Owner.Events.InvokeEvent(new ActivationEvent(pe.Sender, e, pe)));
                    damaged.ForEach(e => Owner.Events.InvokeEvent(new DamageEvent(e, 1, pe.Sender)));
                }

                foreach (PulseReceiver pr in WatchedComponents.Where(c => c is PulseReceiver))
                {
                    if (!pr.Owner.Active)
                    {
                        return;
                    }
                    if (pr.Owner == evt.Sender.Owner)
                    {
                        continue;
                    }

                    Vector2D point = pr.Offset;

                    if (pr.Owner.Components.Get <Spatial>() is Spatial sp)
                    {
                        point += sp.Position;
                    }

                    if (pe.Direction.Magnitude == 0 || GeneralUtil.SubtractAngles((point - pe.Source).Angle, pe.Direction.Angle) <= Math.PI / 4)
                    {
                        double distance = (point - pe.Source).Magnitude;
                        if (distance <= pe.Reach * pr.Sensitivity)
                        {
                            Owner.Events.InvokeEvent(new ActivationEvent(pe.Sender, pr.Owner, pe));
                        }
                    }
                }

                if (!pe.Sender.Owner.Components.Has <PlayerAnimation>())
                {
                    for (int i = 0; i < 5 * Math.Pow(pe.Strength / 16384, 2); i++)
                    {
                        SoundParticle particle = new SoundParticle(pe.Source + pe.Direction * 12, i * 8);
                        Owner.Entities.Add(particle);
                    }
                }
            }
            else if (evt is ActivationEvent e && (pem = e.Affected.Components.Get <PulseEmitterComponent>()) != null)
            {
                Vector2D source = pem.Offset;
                if (pem.Owner.Components.Get <Spatial>() is Spatial sp)
                {
                    source += sp.Position;
                }
                Owner.Events.InvokeEvent(new PulseEvent(pem, source, pem.Direction, pem.Strength, pem.Reach));
            }
        }
Ejemplo n.º 2
0
 private void Awake()
 {
     source = GetComponent <SoundParticle>();
 }