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)); } }
private void Awake() { source = GetComponent <SoundParticle>(); }