Exemplo n.º 1
0
        public override void Render <TSurface, TSource>(ScreenRenderer <TSurface, TSource> r)
        {
            /*var bg = r.GetLayerGraphics("background");
             * bg.Clear(System.Drawing.Color.FromArgb(32, 255, 0, 255));
             * bg.Complete();*/

            var layer = r.GetLayerGraphics("level");

            CameraView view = Owner.CurrentViewport;

            WatchedComponents = WatchedComponents.OrderBy(c => ((LevelRenderable)c).ZOrder).ToList();

            foreach (LevelRenderable tile in WatchedComponents)
            {
                if (!tile.Owner.Active)
                {
                    continue;
                }
                if (tile.Owner.Components.Has <DamageFlashing>() && tile.Owner.Components.Get <Health>() is Health health && ((int)(health.InvincibilityTimer / 6) % 2) != 0)
                {
                    continue;
                }
                if (tile.Owner.Components.Get <Renderable>() is Renderable renderable)
                {
                    Renderable.Render(layer, view, r, renderable.Sprites, renderable.Owner.Components.Get <Spatial>());
                }
            }
        }
Exemplo n.º 2
0
        public override void Update()
        {
            DeathBarrierComponent barrier = null;

            foreach (Component component in WatchedComponents.OrderBy(a => typeOrder.IndexOf(a.GetType())))
            {
                if (component is DeathBarrierComponent)
                {
                    barrier = component as DeathBarrierComponent;
                }
                else if (component is RemoveOnBarrierComponent)
                {
                    if (component.Owner.Components.Get <Transform>() is Transform sp)
                    {
                        if (sp.Position.Y < (barrier?.Y ?? 0))
                        {
                            component.Owner.Remove();
                        }
                    }
                }
                else if (component is CheckpointOnBarrierComponent)
                {
                    if (component.Owner.Components.Get <Transform>() is Transform sp)
                    {
                        if (sp.Position.Y < (barrier?.Y ?? 0))
                        {
                            Owner.Events.InvokeEvent(new CheckpointRequestEvent(barrier, component.Owner));
                        }
                    }
                }
            }
        }
Exemplo n.º 3
0
        public override void EventFired(object sender, Event evt)
        {
            if (evt is PulseEvent pe)
            {
                PlayerComponent player = WatchedComponents.FirstOrDefault() as PlayerComponent;
                if (player == null)
                {
                    return;
                }
                double distance = (pe.Source - player.Owner.Components.Get <Spatial>().Position).Magnitude;
                if (distance < 0.1)
                {
                    distance = 0.1;
                }
                if (distance > 64 && pe.Sender.Owner != player.Owner)
                {
                    return;
                }

                VibrationAmount += Math.Pow(pe.Strength / 256, 2) * 256 / distance;
                if (VibrationAmount < 0.1)
                {
                    VibrationAmount = 0;
                }
            }
        }
Exemplo n.º 4
0
 public override void Update()
 {
     player = WatchedComponents.FirstOrDefault(c => c is PlayerMovementComponent) as PlayerMovementComponent;
     if (AnyDisabled && (player?.OnGround ?? false))
     {
         foreach (EnergyRefillComponent refill in WatchedComponents.OfType <EnergyRefillComponent>())
         {
             if (refill.Enabled)
             {
                 continue;
             }
             refill.Enabled = true;
             Renderable renderable = refill.Owner.GetComponent <Renderable>();
             if (renderable != null && renderable.Sprites.Count >= 1)
             {
                 renderable.Sprites[0].Source = new Rectangle(0, 0, 16, 16);
             }
             AnimationComponent animatable = refill.Owner.GetComponent <AnimationComponent>();
             if (animatable != null && animatable.Animations.Count >= 1 && animatable.Animations[0].SpriteIndex == 0)
             {
                 AnimatedSprite animation = animatable.Animations[0];
                 animation.Loop          = true;
                 animation.CurrentFrame  = 0;
                 animation.LoopFrame     = 5;
                 animation.FrameProgress = 0;
                 animation.FrameDuration = 8;
                 animation.FrameCount    = 9;
                 animation.Frame         = new Rectangle(128, 0, 16, 16);
                 animation.Step          = new Vector2D(-16, 0);
             }
         }
         AnyDisabled = false;
     }
 }
Exemplo n.º 5
0
 public override void Input()
 {
     foreach (SentryAI sentry in WatchedComponents.Where(c => c is SentryAI && c.Owner.Active))
     {
         sentry.OnGround = false;
     }
 }
Exemplo n.º 6
0
        public override void EventFired(object sender, Event re)
        {
            if (re is CheckpointRequestEvent e)
            {
                Spatial  sp = e.EntityToMove.Components.Get <Spatial>();
                Physical ph = e.EntityToMove.Components.Get <Physical>();

                foreach (CheckpointComponent checkpoint in WatchedComponents)
                {
                    if (checkpoint.Selected)
                    {
                        if (sp != null)
                        {
                            sp.Position = checkpoint.Owner.Components.Get <Spatial>().Position;
                        }
                        if (ph != null)
                        {
                            ph.Velocity = Vector2D.Empty;
                        }
                        break;
                    }
                }
            }
            else if (re is SoftCollisionEvent ce &&
                     ce.Victim.Components.Get <CheckpointComponent>() is CheckpointComponent checkpoint &&
                     ce.Sender.Owner.Components.Has <CheckpointTrigger>())
            {
                if (!checkpoint.Selected)
                {
                    WatchedComponents.ForEach(c => (c as CheckpointComponent).Selected = false);
                    checkpoint.Selected = true;
                    System.Console.WriteLine("Changed checkpoint");
                }
            }
        }
Exemplo n.º 7
0
        public override void Render <TSurface, TSource>(ScreenRenderer <TSurface, TSource> r)
        {
            foreach (CounterVariableComponent counter in WatchedComponents.Where(c => c is CounterVariableComponent))
            {
                if (counter.DoRender)
                {
                    Renderable renderable = counter.Owner.Components.Get <Renderable>();
                    if (renderable == null)
                    {
                        continue;
                    }
                    if (renderable.Sprites.Count == 0)
                    {
                        renderable.Sprites.Add(new Sprite("lab_objects", new Rectangle(-4, -8, 8, 16), new Rectangle(0, 400, 8, 16)));
                        renderable.Sprites.Add(new Sprite("lab_objects", new Rectangle(-4, -8, 8, 16), new Rectangle(8, 400, 8, 16)));
                    }

                    if (renderable.Sprites.Count >= 2)
                    {
                        if (counter.EndValue - counter.StartValue == 0)
                        {
                            continue;
                        }
                        float percent = (float)(counter.Value - counter.StartValue) / (counter.EndValue - counter.StartValue);
                        int   height  = (int)Math.Round(percent * 12) + 2;

                        renderable.Sprites[1].Destination.Height = height;
                        renderable.Sprites[1].Source.Y           = 400 + 16 - height;
                        renderable.Sprites[1].Source.Height      = height;
                    }
                }
            }
        }
Exemplo n.º 8
0
 public override void EventFired(object sender, Event e)
 {
     if (e is CameraLocationQueryEvent qe && WatchedComponents.Count > 0)
     {
         qe.SuggestedLocation = WatchedComponents.First().Owner.Components.Get <Transform>().Position +
                                (WatchedComponents.First() as CameraTracked).Offset;
     }
 }
Exemplo n.º 9
0
 public override void EventFired(object sender, Event e)
 {
     if (e is CameraLocationQueryEvent qe && WatchedComponents.Count > 0)
     {
         Owner.Events.InvokeEvent(new CameraLocationResponseEvent(null,
                                                                  WatchedComponents.First().Owner.Components.Get <Spatial>().Position +
                                                                  (WatchedComponents.First() as CameraTracked).Offset,
                                                                  true
                                                                  ));
     }
Exemplo n.º 10
0
 public override void Update()
 {
     foreach (PulseAbility pa in WatchedComponents.Where(c => c is PulseAbility))
     {
         if (pa.Owner.Components.Get <PlayerMovementComponent>().OnGround)
         {
             pa.EnergyMeter = pa.MaxEnergy;
         }
     }
 }
Exemplo n.º 11
0
        public override void Input()
        {
            IInputMap inputMap = Woofer.Controller.InputManager.ActiveInputMap;

            foreach (PulseAbility pa in WatchedComponents.Where(c => c is PulseAbility))
            {
                ButtonInput pulseButton = inputMap.Pulse;

                if (pa.Owner.GetComponent <Health>() is Health health && health.CurrentHealth <= 0)
                {
                    continue;
                }

                if (pa.EnergyMeter >= pa.PulseCost)
                {
                    if (pulseButton.Consume())
                    {
                        double strength = (pa.PulseStrength * Math.Sqrt(pa.EnergyMeter / pa.MaxEnergy));

                        if (pa.Owner.Components.Has <Physical>() && pa.Owner.Components.Has <PlayerOrientation>())
                        {
                            pa.Owner.Components.Get <Physical>().Velocity = pa.Owner.Components.Get <PlayerOrientation>().Unit * -strength;

                            ISoundEffect sound_low = Woofer.Controller.AudioUnit["pulse_low"];
                            sound_low.Pitch = (float)(strength / 256) - 1;
                            ISoundEffect sound_mid = Woofer.Controller.AudioUnit["pulse_mid"];
                            sound_mid.Pitch = sound_low.Pitch;
                            ISoundEffect sound_high = Woofer.Controller.AudioUnit["pulse_high"];
                            sound_high.Pitch = sound_low.Pitch;

                            sound_low.Volume = 0.6f;


                            sound_low.Play();
                            sound_mid.Play();
                            sound_high.Play();
                        }

                        pa.EnergyMeter -= pa.PulseCost;

                        if (pa.Owner.Components.Has <Spatial>())
                        {
                            Spatial sp = pa.Owner.Components.Get <Spatial>();
                            if (sp == null)
                            {
                                continue;
                            }
                            PlayerOrientation po = pa.Owner.Components.Get <PlayerOrientation>();

                            Owner.Events.InvokeEvent(new PulseEvent(pa, sp.Position + pa.Offset, po != null ? po.Unit : new Vector2D(), strength, pa.MaxRange));
                        }
                    }
                }
            }
        }
Exemplo n.º 12
0
        public override void Input()
        {
            IEnumerable <InteractingAgent> agents = WatchedComponents.Where(c => c is InteractingAgent && c.Owner.Active).Select(c => c as InteractingAgent);

            foreach (Component rawC in WatchedComponents)
            {
                if (!rawC.Owner.Active)
                {
                    continue;
                }
                if (rawC is Interactable interactable)
                {
                    InteractingAgent currentAgent = null;
                    bool             inRange      = false;
                    foreach (InteractingAgent agent in agents)
                    {
                        if ((agent.Owner.Components.Get <Spatial>().Position - interactable.Owner.Components.Get <Spatial>().Position).Magnitude <= agent.MaxDistance)
                        {
                            currentAgent = agent;
                            inRange      = true;
                            break;
                        }
                    }
                    if (inRange != interactable.InRange)
                    {
                        if (inRange)
                        {
                            CurrentInteractions[interactable] = currentAgent;
                        }
                        else
                        {
                            CurrentInteractions.Remove(interactable);
                        }
                        Owner.Events.InvokeEvent(inRange ?
                                                 (Event) new InteractionRangeEnter(currentAgent, interactable) :
                                                 (Event) new InteractionRangeExit(null));
                        interactable.InRange = inRange;
                    }

                    if (inRange)
                    {
                        ButtonInput interact = Woofer.Controller.InputManager.ActiveInputMap.Interact;

                        if (interact.Consume())
                        {
                            Entity sendTo = interactable.EntityToActivate != 0 ? Owner.Entities[interactable.EntityToActivate] : interactable.Owner;
                            Owner.Events.InvokeEvent(new ActivationEvent(currentAgent, sendTo, null));
                        }
                    }
                }
            }
        }
Exemplo n.º 13
0
        public override void Update()
        {
            if (Focused == null)
            {
                return;
            }
            InteractionIcon icon = WatchedComponents.FirstOrDefault() as InteractionIcon;

            if (icon == null)
            {
                return;
            }
            icon.Owner.Components.Get <Spatial>().Position = Focused.Owner.Components.Get <Spatial>().Position + Focused.IconOffset;
        }
Exemplo n.º 14
0
        public override void EventFired(object sender, Event e)
        {
            if (e is RaycastEvent re)
            {
                //Initialize list of intersections
                if (re.Intersected == null)
                {
                    re.Intersected = new List <RaycastIntersection>();
                }

                //Filter all soft and rigid bodies whose X axis intersects the given ray.
                List <Component> intersectingX = WatchedComponents.Where(c => !(c is Physical) && c.Owner.Active && (IntersectsX(c, re.Ray.A.X, re.Ray.B.X))).ToList();

                foreach (Component c in intersectingX)
                {
                    Physical  phys = c.Owner.Components.Get <Physical>();
                    Transform sp   = c.Owner.Components.Get <Transform>();

                    IEnumerable <CollisionBox> solidBoxes =
                        c is SoftBody ?
                        new CollisionBox[] { (c as SoftBody).Bounds.Offset(phys?.Position ?? sp?.Position ?? Vector2D.Empty) } :
                    (c as RigidBody).Bounds.Select(b => b.Offset(phys?.Position ?? sp?.Position ?? Vector2D.Empty));

                    foreach (CollisionBox box in solidBoxes)
                    {
                        List <FreeVector2D> sides = box.GetSides();
                        foreach (FreeVector2D side in sides)
                        {
                            Vector2D?intersection = re.Ray.GetIntersection(side);
                            if (intersection.HasValue)
                            {
                                re.Intersected.Add(new RaycastIntersection(intersection.Value, side, box, c, box.GetFaceProperties(side.Normal)));
                            }
                        }
                    }
                }
            }
            else if ((e is RigidCollisionEvent || e is SoftCollisionEvent) && e.Sender.Owner.Components.Get <RemoveOnCollision>() is RemoveOnCollision remove)
            {
                if ((remove.RemoveOnRigid && e is RigidCollisionEvent) || (remove.RemoveOnSoft && e is SoftCollisionEvent))
                {
                    e.Sender.Owner.Remove();
                }
            }
        }
Exemplo n.º 15
0
        public override void Input()
        {
            IInputMap inputMap = Woofer.Controller.InputManager.ActiveInputMap;

            foreach (PulseAbility pa in WatchedComponents.Where(c => c is PulseAbility))
            {
                ButtonState pulseButton = inputMap.Pulse;

                if (pulseButton.IsPressed())
                {
                    pa.Pulse.RegisterPressed();
                }
                else
                {
                    pa.Pulse.RegisterUnpressed();
                }

                if (pa.EnergyMeter >= pa.PulseCost)
                {
                    if (pulseButton.IsPressed() && pa.Pulse.Execute())
                    {
                        double strength = (pa.PulseStrength * Math.Sqrt(pa.EnergyMeter / pa.MaxEnergy));

                        if (pa.Owner.Components.Has <Physical>() && pa.Owner.Components.Has <PlayerOrientation>())
                        {
                            pa.Owner.Components.Get <Physical>().Velocity = pa.Owner.Components.Get <PlayerOrientation>().Unit * -strength;
                        }

                        pa.EnergyMeter -= pa.PulseCost;

                        if (pa.Owner.Components.Has <Spatial>())
                        {
                            Spatial sp = pa.Owner.Components.Get <Spatial>();
                            if (sp == null)
                            {
                                continue;
                            }
                            PlayerOrientation po = pa.Owner.Components.Get <PlayerOrientation>();

                            Owner.Events.InvokeEvent(new PulseEvent(pa, sp.Position, po != null ? po.Unit : new Vector2D(), strength, pa.MaxRange));
                        }
                    }
                }
            }
        }
Exemplo n.º 16
0
        public override void Update()
        {
            foreach (PlayerComponent player in WatchedComponents.OfType <PlayerComponent>())
            {
                if (!player.Initialized)
                {
                    Entity entity = player.Owner;
                    if (Woofer.Controller.CurrentSave.Data.HasWoofer)
                    {
                        entity.Components.Add(new PulseAbility());
                        entity.Components.Get <PulseAbility>().MaxEnergy = Woofer.Controller.CurrentSave.Data.MaxEnergy;
                    }
                    else
                    {
                        entity.Components.Remove <PulseAbility>();
                    }
                    if (!entity.Components.Has <Health>())
                    {
                        entity.Components.Add(new Health());
                    }
                    entity.Components.Add(new DamageFlashing());
                    Health health = entity.Components.Get <Health>();
                    bool   heal   = health.CurrentHealth == health.MaxHealth;
                    health.MaxHealth = Woofer.Controller.CurrentSave.Data.MaxHealth;
                    if (heal)
                    {
                        health.CurrentHealth = health.MaxHealth;
                    }
                    health.HealthBarOffset = new Vector2D(0, 32);
                    health.RemoveOnDeath   = false;
                    player.Initialized     = true;

                    foreach (Component listener in WatchedComponents.OfType <OnLoadTrigger>())
                    {
                        Owner.Events.InvokeEvent(new ActivationEvent(player, listener.Owner, null));
                    }
                }
            }
        }
Exemplo n.º 17
0
        public override void EventFired(object sender, Event evt)
        {
            InteractionIcon icon = WatchedComponents.FirstOrDefault() as InteractionIcon;

            if (icon == null)
            {
                return;
            }
            if (evt is InteractionRangeEnter enter)
            {
                if (enter.Interactable.Owner.Components.Has <Spatial>())
                {
                    icon.Owner.Active = true;
                    icon.Owner.Components.Get <Spatial>().Position = enter.Interactable.Owner.Components.Get <Spatial>().Position + enter.Interactable.IconOffset;
                    Focused = enter.Interactable;
                }
            }
            else if (evt is InteractionRangeExit)
            {
                icon.Owner.Active = false;
                Focused           = null;
            }
        }
Exemplo n.º 18
0
 public override void EventFired(object sender, Event e)
 {
     if (e is ActivationEvent ae && ae.Affected.GetComponent <EntitySpawner>() is EntitySpawner spawner)
     {
         if (spawner.MaxEntities <= 0 || WatchedComponents.OfType <Spawned>().Count(c => c.SpawnerId == spawner.Owner.Id) < spawner.MaxEntities)
         {
             Entity toCopy = Owner.Entities[spawner.Blueprint];
             if (toCopy != null)
             {
                 Entity clone = TagIOUtils.CloneEntity(toCopy);
                 if (clone.GetComponent <Transform>() is Transform sp && spawner.Owner.GetComponent <Transform>() is Transform spawnerSp)
                 {
                     sp.Position = spawnerSp.Position;
                 }
                 clone.Active = true;
                 clone.Components.Add(new Spawned()
                 {
                     SpawnerId = spawner.Owner.Id
                 });
                 Owner.Entities.Add(clone);
             }
         }
     }
 }
Exemplo n.º 19
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));
            }
        }
Exemplo n.º 20
0
        public override void EventFired(object sender, Event evt)
        {
            if (evt is ActivationEvent ae)
            {
                if (ae.Affected.Components.Has <WooferGiverComponent>())
                {
                    Entity player = WatchedComponents.FirstOrDefault()?.Owner;
                    if (player == null)
                    {
                        return;
                    }
                    ae.Affected.Active = false;
                    if (!player.Components.Has <PulseAbility>())
                    {
                        player.Components.Add(new PulseAbility());
                        Woofer.Controller.CurrentSave.Data.HasWoofer = true;
                        Woofer.Controller.CommandFired(new SaveCommand());

                        Owner.Events.InvokeEvent(new ShowTextEvent(new Sprite("x_icons", new Rectangle(0, 0, 9, 9), new Rectangle(0, 9, 9, 9))
                        {
                            Modifiers = Sprite.Mod_InputType
                        }, "Activate", ae.Sender)
                        {
                            Duration = 10
                        });
                    }
                }
                if (ae.Affected.Components.Get <WooferUpgradeComponent>() is WooferUpgradeComponent wooferUpgrade)
                {
                    Entity player = WatchedComponents.FirstOrDefault()?.Owner;
                    if (player == null)
                    {
                        return;
                    }
                    ae.Affected.Active = false;
                    Woofer.Controller.CurrentSave.Data.MaxEnergy = Math.Max(Woofer.Controller.CurrentSave.Data.MaxEnergy, wooferUpgrade.Energy);
                    if (player.GetComponent <PulseAbility>() is PulseAbility pulse)
                    {
                        pulse.MaxEnergy   = Woofer.Controller.CurrentSave.Data.MaxEnergy;
                        pulse.EnergyMeter = pulse.MaxEnergy;
                    }
                    Woofer.Controller.CommandFired(new SaveCommand());
                    Transform sp = ae.Affected.GetComponent <Transform>();
                    if (sp != null)
                    {
                        Owner.Entities.Add(new SoundParticle(sp.Position));
                    }
                    Owner.Controller.AudioUnit["refill"].Play();

                    Owner.Events.InvokeEvent(new ShowTextEvent(new Sprite("x_icons", new Rectangle(0, 0, 9, 9), new Rectangle(0, 9, 9, 9))
                    {
                        Modifiers = Sprite.Mod_InputType
                    }, "Activate", ae.Sender)
                    {
                        Duration = 10
                    });
                }
                if (ae.Affected.Components.Get <HealthUpgradeComponent>() is HealthUpgradeComponent healthUpgrade)
                {
                    Entity player = WatchedComponents.FirstOrDefault()?.Owner;
                    if (player == null)
                    {
                        return;
                    }
                    ae.Affected.Active = false;
                    Woofer.Controller.CurrentSave.Data.MaxHealth = Math.Max(Woofer.Controller.CurrentSave.Data.MaxHealth, healthUpgrade.Health);
                    if (player.GetComponent <Health>() is Health health)
                    {
                        health.MaxHealth        = Woofer.Controller.CurrentSave.Data.MaxHealth;
                        health.CurrentHealth    = health.MaxHealth;
                        health.RegenCooldown    = health.RegenRate;
                        health.HealthBarVisible = true;
                    }
                    Woofer.Controller.CommandFired(new SaveCommand());
                    Transform sp = ae.Affected.GetComponent <Transform>();
                    if (sp != null)
                    {
                        Owner.Entities.Add(new SoundParticle(sp.Position));
                    }
                    Owner.Controller.AudioUnit["refill"].Play();
                }
            }
            else if (evt is DeathEvent de && de.Affected.HasComponent <PlayerComponent>())
            {
                Health health = de.Affected.GetComponent <Health>();
                if (health != null)
                {
                    health.RemoveOnDeath = false;
                    health.CurrentHealth = health.MaxHealth;
                }
                Owner.Events.InvokeEvent(new CheckpointRequestEvent(de.Affected.GetComponent <PlayerComponent>(), de.Affected));
            }
        }
Exemplo n.º 21
0
        public override void Update()
        {
            Entity player = WatchedComponents.FirstOrDefault()?.Owner;

            if (player == null)
            {
                return;
            }
            Transform playerSp = player.Components.Get <Transform>();

            if (playerSp == null)
            {
                return;
            }

            foreach (SentryAI sentry in WatchedComponents.Where(c => c is SentryAI && c.Owner.Active))
            {
                if (sentry.ActionTime > 0)
                {
                    sentry.ActionTime--;
                }
                if ((sentry.Owner.Components.Get <Health>()?.CurrentHealth ?? 1) <= 0)
                {
                    continue;
                }
                Transform sp   = sentry.Owner.Components.Get <Transform>();
                Physical  phys = sentry.Owner.Components.Get <Physical>();
                if (sp == null || phys == null)
                {
                    continue;
                }
                bool inRange = (sp.Position - playerSp.Position).Magnitude < sentry.FollowDistance;

                if (sentry.Action == SentryAction.Throw && sentry.ActionTime == 30)
                {
                    Vector2D velocity   = new Vector2D();
                    double   targetTime = 0.8;
                    velocity.X = (playerSp.Position.X - sp.Position.X) / targetTime;
                    velocity.Y = ((playerSp.Position.Y - sp.Position.Y - 4) + (362 * targetTime * targetTime) / 2) / targetTime;
                    velocity   = velocity.Normalize() * Math.Min(velocity.Magnitude, 256);

                    Owner.Entities.Add(new Projectile(sentry.Owner, sp.Position + new Vector2D(0, 4), velocity));
                }

                if (!sentry.OnGround)
                {
                    continue;
                }

                if (inRange && sentry.ActionTime == 0)
                {
                    //Choose action

                    double distance = (playerSp.Position - sp.Position).Magnitude;

                    int[] weights = { 1, 2, 3 };
                    if (distance > 64)
                    {
                        weights[0] = 10;
                    }
                    else if (distance < 48)
                    {
                        weights[1] = 6;
                    }
                    else
                    {
                        weights[2] = 4;
                    }

                    SentryAction next;

                    int pick = Random.Next(weights[0] + weights[1] + weights[2]);
                    if (pick < weights[0])
                    {
                        next = SentryAction.Charge;
                    }
                    else if (pick < weights[0] + weights[1])
                    {
                        next = SentryAction.Dodge;
                    }
                    else
                    {
                        next = SentryAction.Throw;
                    }

                    sentry.Action = next;

                    switch (next)
                    {
                    case SentryAction.Charge:
                    {
                        phys.Velocity     = new Vector2D(128 * Math.Sign(playerSp.Position.X - sp.Position.X), 64);
                        sentry.ActionTime = Random.Next(30, 60);
                        break;
                    }

                    case SentryAction.Dodge:
                    {
                        phys.Velocity     = new Vector2D(-64 * Math.Sign(playerSp.Position.X - sp.Position.X), 64);
                        sentry.ActionTime = Random.Next(30, 60);
                        break;
                    }

                    case SentryAction.Throw:
                    {
                        sentry.ActionTime = 80;
                        break;
                    }
                    }
                }
            }
        }
Exemplo n.º 22
0
        public override void Update()
        {
            if (Owner.FixedDeltaTime == 0)
            {
                return;
            }
            accumulator += Owner.DeltaTime;

            int timesExecuted = 0;

            while (accumulator >= Owner.FixedDeltaTime)
            {
                timesExecuted++;
                accumulator -= Owner.FixedDeltaTime;
                foreach (Physical ph in WatchedComponents.Where(c => c is Physical))
                {
                    if (!ph.Owner.Active)
                    {
                        continue;
                    }
                    ph.PreviousPosition = ph.Position;

                    ph.Velocity += Gravity * ph.GravityMultiplier * Owner.FixedDeltaTime;
                    ph.Position += ph.Velocity * Owner.FixedDeltaTime;

                    ph.Position = ph.Position.GetRounded();
                    ph.Velocity = ph.Velocity.GetRounded();

                    ph.PreviousVelocity = ph.Velocity;
                }

                WatchedComponents = WatchedComponents.OrderBy(a => GetCrossTickLeft(a)).ToList();

                //Handle collision
                foreach (Component c0 in WatchedComponents)
                {
                    if (c0 is Physical)
                    {
                        continue;
                    }
                    if (!c0.Owner.Active)
                    {
                        continue;
                    }
                    double x = GetCrossTickLeft(c0);

                    while (sweeper.Count > 0 && !IntersectsX(sweeper[0], x))
                    {
                        sweeper.RemoveAt(0);
                    }

                    foreach (Component c1 in sweeper)
                    {
                        if (c0 is RigidBody && c1 is RigidBody)
                        {
                            continue;
                        }

                        SoftBody  objA = c0 is SoftBody ? (SoftBody)c0 : (SoftBody)c1;
                        Component objB = objA == c0 ? c1 : c0;

                        if (objA.PassThroughLevel && objB is RigidBody)
                        {
                            continue;
                        }

                        Physical physA = objA.Owner.Components.Get <Physical>();
                        Physical physB = objB.Owner.Components.Get <Physical>();

                        if (physA == null || physB == null)
                        {
                            continue;
                        }

                        if (objB is RigidBody rb && !rb.UnionBounds.Offset(physB.Position).IntersectsWith(objA.Bounds.Offset(physA.Position)))
                        {
                            continue;
                        }

                        IEnumerable <CollisionBox> solidBoxes =
                            objB is SoftBody ?
                            new CollisionBox[] { (objB as SoftBody).Bounds.Offset(physB.Position) } :
                        (objB as RigidBody).Bounds.Select(b => b.Offset(physB.Position));

                        foreach (CollisionBox otherBounds in solidBoxes)
                        {
                            CollisionBox intersection = objA.Bounds.Offset(physA.Position).Intersect(otherBounds);
                            if (intersection != null)
                            {
                                collisions.Add(new SingleCollision(objA, objB, otherBounds, intersection));
                            }
                        }
                    }

                    foreach (SingleCollision collision in collisions.OrderByDescending(c => c.intersection.Area))
                    {
                        SoftBody  objA = collision.objA;
                        Component objB = collision.objB;

                        Physical physA = objA.Owner.Components.Get <Physical>();
                        Physical physB = objB.Owner.Components.Get <Physical>();

                        CollisionBox otherBounds  = collision.box;
                        CollisionBox intersection = objA.Bounds.Offset(physA.Position).Intersect(otherBounds);

                        if (intersection == null)
                        {
                            continue;
                        }

                        if (objB is RigidBody) //Hard collision
                        {
                            Vector2D totalVelocity = physA.PreviousVelocity - physB.Velocity;

                            List <FreeVector2D> sides = intersection.GetSides().Where(s => BelongsToBox(s, otherBounds)).Where(s => GeneralUtil.SubtractAngles(s.Normal.Angle, totalVelocity.Angle) > Math.PI / 2).ToList();

                            if (sides.Count == 0) //It's "stuck" inside a tile or that tile doesn't have one of the sides enabled
                            {
                                continue;
                            }

                            FreeVector2D normalSide = sides[0];
                            Vector2D     normal     = sides[0].Normal;
                            if (normal == Vector2D.Empty)
                            {
                                continue;
                            }

                            if (sides.Count > 1)
                            {
                                if (IsAheadOfNormal(objA.Bounds.Offset(physA.PreviousPosition), sides[0]))
                                {
                                    if (IsAheadOfNormal(objA.Bounds.Offset(physA.PreviousPosition), sides[1]))
                                    {
                                        normalSide = sides[0].Normal.X == 0 ? sides[0] : sides[1];
                                    }
                                    else
                                    {
                                        normalSide = sides[0];
                                    }
                                }
                                else
                                {
                                    normalSide = sides[1];
                                }

                                normal = normalSide.Normal;
                            }
                            CollisionFaceProperties faceProperties = intersection.GetFaceProperties(normal);

                            if (objA.Movable)
                            {
                                if (normal.X == 0)
                                {
                                    double displacement = Math.Abs(normalSide.A.Y - (normal.Y > 0 ? objA.Bounds.Offset(physA.Position).Bottom : objA.Bounds.Offset(physA.Position).Top));
                                    if (faceProperties.Snap || Math.Round(displacement, 8) <= Math.Round(Math.Abs(physA.Position.Y - physA.PreviousPosition.Y) + Math.Abs(physB.Position.Y - physB.PreviousPosition.Y), 8))
                                    {
                                        physA.Position += new Vector2D(0, displacement) * normal.Y;
                                        physA.Velocity  = new Vector2D(physA.Velocity.X * (1 - faceProperties.Friction), 0) + physB.Velocity * faceProperties.Friction;
                                    }
                                    else
                                    {
                                        continue;
                                    }
                                }
                                else
                                {
                                    double displacement = Math.Abs(normalSide.A.X - (normal.X > 0 ? objA.Bounds.Offset(physA.Position).Left : objA.Bounds.Offset(physA.Position).Right));
                                    if (faceProperties.Snap || Math.Round(displacement, 8) <= Math.Round(Math.Abs(physA.Position.X - physA.PreviousPosition.X) + Math.Abs(physB.Position.X - physB.PreviousPosition.X), 8))
                                    {
                                        physA.Position += new Vector2D(displacement, 0) * normal.X;
                                        physA.Velocity  = new Vector2D(0, physA.Velocity.Y * (1 - faceProperties.Friction)) + physB.Velocity * faceProperties.Friction;
                                    }
                                    else
                                    {
                                        continue;
                                    }
                                }
                            }

                            Owner.Events.InvokeEvent(new RigidCollisionEvent(objA, objB.Owner, normal));
                            Owner.Events.InvokeEvent(new RigidCollisionEvent(objB, objA.Owner, normal));
                        }
                        else //Soft Collision
                        {
                            Owner.Events.InvokeEvent(new SoftCollisionEvent(objA, objB.Owner));
                            Owner.Events.InvokeEvent(new SoftCollisionEvent(objB, objA.Owner));

                            Vector2D center0 = objA.Bounds.Offset(physA.Position).Center;
                            Vector2D center1 = otherBounds.Center;

                            double distance = (center0 - center1).Magnitude;
                            if (distance <= 1e-4)
                            {
                                continue;
                            }

                            double force = 2 * Owner.FixedDeltaTime * intersection.Area * (objA.Mass * (objB as SoftBody).Mass);

                            Vector2D forceVec = (center1 - center0).Normalize() * force;
                            forceVec.Y = 0;

                            if (objA.Movable && objA.Mass != 0)
                            {
                                physA.Velocity -= forceVec / (objA.Mass);
                            }
                            if ((objB as SoftBody).Movable && (objB as SoftBody).Mass != 0)
                            {
                                physB.Velocity -= -forceVec / (objB as SoftBody).Mass;
                            }
                        }
                    }

                    collisions.Clear();

                    sweeper.Add(c0);
                }
            }

            sweeper.Clear();
            collisions.Clear();
        }
Exemplo n.º 23
0
        public override void EventFired(object sender, Event re)
        {
            if (re is PulseEvent)
            {
                PulseEvent e = re as PulseEvent;

                foreach (PulsePushable pp in WatchedComponents.Where(c => c is PulsePushable))
                {
                    if (!pp.Owner.Active)
                    {
                        continue;
                    }
                    if (pp.Owner == re.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 - e.Source).Magnitude;

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

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

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

                    Vector2D point = pr.Offset;

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

                    if (e.Source.Magnitude == 0 || GeneralUtil.SubtractAngles((point - e.Source).Angle, e.Direction.Angle) <= Math.PI / 4)
                    {
                        double distance = (point - e.Source).Magnitude;
                        if (distance <= e.Reach * pr.Sensitivity)
                        {
                            Owner.Events.InvokeEvent(new ActivationEvent(e.Sender, pr.Owner, e));
                        }
                    }
                }
            }
        }
Exemplo n.º 24
0
        public override void Update()
        {
            Entity player = WatchedComponents.OfType <PlayerComponent>().FirstOrDefault()?.Owner;

            foreach (Boss boss in WatchedComponents.OfType <Boss>())
            {
                if (boss.Health <= 0)
                {
                    continue;
                }
                Transform sp   = boss.Owner.GetComponent <Transform>();
                Physical  phys = boss.Owner.GetComponent <Physical>();

                Transform playerSp = player?.GetComponent <Transform>();
                if (sp == null || phys == null)
                {
                    continue;
                }

                phys.GravityMultiplier = 1;
                phys.Velocity          = new Vector2D(0, 362) * Owner.DeltaTime;

                Vector2D?flyTo    = null;
                float    flySpeed = 1;

                bool showParticles = true;

                boss.Difficulty = boss.Health > 20 ? 0 : 1;

                if (boss.State == Boss.Circling)
                {
                    if (boss.Transitioning)
                    {
                        if ((sp.Position - new Vector2D(0, boss.Difficulty >= 1 ? 192 : 128)).Magnitude < 1)
                        {
                            boss.Transitioning = false;
                            boss.StateData     = 0;
                        }
                        else
                        {
                            flyTo    = new Vector2D(0, boss.Difficulty >= 1 ? 192 : 128);
                            flySpeed = 2;
                        }
                    }
                    if (!boss.Transitioning)
                    {
                        boss.StateData += Owner.DeltaTime;
                        if (boss.StateData > 16)
                        {
                            boss.ChangeState(Owner.Random.Next(4) == 0 ? Boss.Drop : Boss.Laser);
                        }
                        else
                        {
                            phys.Velocity += new Vector2D(125.6 * Math.Cos(Math.PI * boss.StateData / 4), 0);
                            Vector2D hoverVelocity = new Vector2D(0, 48 * Math.Cos(Math.PI * boss.StateData));
                            phys.Velocity += hoverVelocity;

                            if (boss.Difficulty >= 1 && Math.Round(boss.StateData, 3) % 4 == 0)
                            {
                                Owner.Entities.Add(new BossProjectileEntity(sp.Position + new Vector2D(0, -48)));
                            }
                        }
                    }
                }
                else if (boss.State == Boss.Laser)
                {
                    if (boss.Transitioning)
                    {
                        if ((sp.Position - new Vector2D(boss.Difficulty >= 1 ? 160 : 0, 256)).Magnitude < 1)
                        {
                            boss.Transitioning = false;
                            boss.StateData     = 0;
                        }
                        else
                        {
                            flyTo    = new Vector2D(boss.Difficulty >= 1 ? 160 : 0, 256);
                            flySpeed = 2;
                        }
                    }
                    if (!boss.Transitioning)
                    {
                        boss.StateData += Owner.DeltaTime;
                        if (boss.Difficulty < 1 && boss.StateData < 1.5)
                        {
                            if (playerSp != null)
                            {
                                flyTo = new Vector2D(playerSp.Position.X, sp.Position.Y);
                            }
                        }
                        else
                        {
                            if (boss.FlameEntity != 0)
                            {
                                Entity entity = Owner.Entities[boss.FlameEntity];
                                if (entity != null)
                                {
                                    entity.Active = false;
                                }
                            }
                            var laser1 = new BossLaser(sp.Position + new Vector2D(0, -44), true);
                            var laser2 = new BossLaser(sp.Position + new Vector2D(-88, -76), false);
                            var laser3 = new BossLaser(sp.Position + new Vector2D(88, -76), false);
                            laser1.Components.Add(new FollowingComponent(boss.Owner.Id)
                            {
                                Offset = new Vector2D(0, -44)
                            });
                            laser2.Components.Add(new FollowingComponent(boss.Owner.Id)
                            {
                                Offset = new Vector2D(-88, -76)
                            });
                            laser3.Components.Add(new FollowingComponent(boss.Owner.Id)
                            {
                                Offset = new Vector2D(88, -76)
                            });
                            Owner.Entities.Add(laser1);
                            Owner.Entities.Add(laser2);
                            Owner.Entities.Add(laser3);
                            boss.ChangeState(Boss.LaserIdle);
                            showParticles = false;
                        }
                    }
                }
                else if (boss.State == Boss.LaserIdle)
                {
                    boss.Transitioning = false;
                    boss.StateData    += Owner.DeltaTime;
                    if (boss.StateData >= 5)
                    {
                        if (boss.FlameEntity != 0)
                        {
                            Entity entity = Owner.Entities[boss.FlameEntity];
                            if (entity != null)
                            {
                                entity.Active = true;
                            }
                        }
                        boss.ChangeState(Boss.Circling);
                    }
                    else
                    {
                        if (boss.Difficulty >= 1)
                        {
                            phys.Velocity += new Vector2D(-64, 0);
                        }
                        showParticles = false;
                    }
                }
                else if (boss.State == Boss.Drop)
                {
                    if (boss.Transitioning)
                    {
                        if ((sp.Position - new Vector2D(-160, 256)).Magnitude < 1)
                        {
                            boss.Transitioning = false;
                            boss.StateData     = 0;
                        }
                        else
                        {
                            flyTo    = new Vector2D(-160, 256);
                            flySpeed = 2;
                        }
                    }
                    if (!boss.Transitioning)
                    {
                        if (sp.Position.X >= 160)
                        {
                            boss.ChangeState(Boss.Circling);
                        }
                        else
                        {
                            boss.StateData += Owner.DeltaTime;
                            phys.Velocity  += new Vector2D(96, 0);
                            if (boss.StateData >= 1)
                            {
                                boss.StateData = 0;
                                if (boss.SentrySpawnerEntity != 0)
                                {
                                    Entity spawner = Owner.Entities[boss.SentrySpawnerEntity];
                                    if (spawner != null)
                                    {
                                        Owner.Events.InvokeEvent(new ActivationEvent(boss, spawner, null));
                                    }
                                }
                            }
                        }
                    }
                }

                //Functions
                if (flyTo != null)
                {
                    phys.Velocity += flySpeed * (flyTo.Value - sp.Position);
                }

                //Particles
                if (showParticles && (boss.FlameParticleProgress == 0 || boss.FlameParticleProgress == 5 * 3 || boss.FlameParticleProgress == 5 * 5 || boss.FlameParticleProgress == 2 * 5 || boss.FlameParticleProgress == 7 * 5))
                {
                    int variant  = boss.FlameParticleProgress == 0 ? 0 : boss.FlameParticleProgress == 3 * 5 ? 1 : boss.FlameParticleProgress == 5 * 5 ? 2 : boss.FlameParticleProgress == 2 * 5 ? 3 : 4;
                    var particle = new BossFlameParticle(sp.Position + phys.Velocity * Owner.DeltaTime + new Vector2D(0, -40), variant);
                    particle.GetComponent <Physical>().Velocity = phys.Velocity * 0.35;
                    Owner.Entities.Add(particle);
                }
                boss.FlameParticleProgress++;
                if (boss.FlameParticleProgress >= 5 * 8)
                {
                    boss.FlameParticleProgress = 0;
                }
            }
        }