예제 #1
0
        public override async Task Execute()
        {
            // Play explosion sound
            AudioEmitterComponent audioEmitter = Entity.Get <AudioEmitterComponent>();

            explosionSound = audioEmitter["Explosion"];
            explosionSound.PlayAndForget();

            Entity.Transform.UpdateWorldMatrix();

            var model = Entity.Get <ModelComponent>();

            // Scatter all the Rigidbody parts of the scattered drone model
            var     fracturedRigidBodies = Entity.GetAll <RigidbodyComponent>();
            Vector3 explosionCenter      = Entity.Transform.WorldMatrix.TranslationVector;
            Random  explosionRandom      = new Random();

            foreach (var fragment in fracturedRigidBodies)
            {
                Vector3 dir = fragment.PhysicsWorldTransform.TranslationVector - explosionCenter;
                dir.Normalize();

                fragment.IsKinematic = false;
                if (model.Skeleton.Nodes[fragment.BoneIndex].Name != "Drone_D_part_015")
                {
                    fragment.ApplyTorqueImpulse(-dir * (float)(explosionRandom.NextDouble() * 0.2f));
                    fragment.ApplyImpulse(dir * (float)(explosionRandom.NextDouble() * 2.5f + 2.5f));
                }
            }

            await Task.Delay(30000);

            // Despawn after a while to clean up drone parts
            SceneSystem.SceneInstance.RootScene.Entities.Remove(Entity);
        }
예제 #2
0
        private void Reload()
        {
            var bulletDelta = 1.0f / BulletPerSeconds;

            lastBullet  = Game.UpdateTime.Total + TimeSpan.FromSeconds(1.5 - bulletDelta);
            IsReloading = true;
            OnReload?.Invoke(this);

            // Play reload sound
            reloadSound.PlayAndForget();
        }
예제 #3
0
        public void Damage(int damage)
        {
            bool wasDead = IsDead;

            // Let's keep the godmode for now
            //HealthPoints = Math.Max(0, HealthPoints - damage);
            if (HealthPoints > 0)
            {
                Game.VibratorSmooth(controllerIndex, new Vector2(0.50f, 0.45f), new Vector2(0.95f, 0.90f), TimeSpan.FromSeconds(0.5));

                // Stop other hit sounds
                for (int i = 0; i < hitSounds.Length; i++)
                {
                    hitSounds[i].Stop();
                }

                // Play being hit sound
                hitSounds[soundIndexGenerator.Next(0, hitSounds.Length - 1)].PlayAndForget();
            }
            else
            {
                // Only do this once, when dying
                if (!wasDead)
                {
                    // Play dying sound
                    deathSound.PlayAndForget();

                    Game.VibratorSmooth(controllerIndex, new Vector2(0.90f, 0.99f), new Vector2(0.0f, 0.0f), TimeSpan.FromSeconds(3));
                    Move(0.0f); //stop any motion
                    stateMachine?.SwitchTo(IdleState);
                    stateMachine?.Exit();
                    Script.AddTask(async() =>
                    {
                        await Game.WaitTime(TimeSpan.FromSeconds(3));
                        IsAlive = false;
                    });
                }
            }

            // Fire event
            OnDamageTaken?.Invoke(this, damage);
        }
예제 #4
0
        protected override async Task Explode()
        {
            var model = Entity.Get <ModelComponent>();

            model.Enabled = false;

            ExplosionParticle.Enabled = true;

            //stop spawning smoke particles
            SmokeParticle.ParticleSystem.StopEmitters();

            //find what we hit
            foreach (var collision in sensor.Collisions)
            {
                var collider      = collision.ColliderA == sensor ? collision.ColliderB : collision.ColliderA;
                var damagedEntity = Utils.GetDestructible(collider.Entity);
                if (damagedEntity == null || damagedEntity.IsDead)
                {
                    continue;
                }

                // Don't damage other drones
                if (damagedEntity is Drone)
                {
                    continue;
                }

                var firstContact = collision.Contacts.First();

                var damage = (int)((0.25f + 0.75f * Math.Abs(firstContact.Distance) / AoE) * Damage);
                damagedEntity.Damage(damage);
            }

            explodeSound.PlayAndForget();

            // Wait before Destroying the rocket
            await Task.Delay(2000);
        }
예제 #5
0
        /// <summary>
        /// Spawns rockets in a grid
        /// </summary>
        protected override async Task Shoot(Entity targetEntity)
        {
            // Play shooting animation
            Drone.Animation.Shoot();

            // Wait a bit
            await Task.Delay(TimeSpan.FromSeconds(AnimationDelay));

            List <Projectile> projectiles = new List <Projectile>();

            Vector2 stepOffset = new Vector2(1.0f / ArraySize.X, 1.0f / ArraySize.Y) * ArrayExtent;

            // Generate random spawn position
            List <Vector2> spawnOffsets = new List <Vector2>();

            for (int y = 0; y < ArraySize.Y; y++)
            {
                float stepY = (ArraySize.Y == 0) ? 0.0f : (y / (float)(ArraySize.Y - 1) * 2.0f - 1.0f);
                for (int x = 0; x < ArraySize.X; x++)
                {
                    float   stepX       = (ArraySize.X == 0) ? 0.0f : (x / (float)(ArraySize.X - 1) * 2.0f - 1.0f);
                    Vector2 spawnOffset = new Vector2((stepOffset.X * stepX), (stepOffset.Y * stepY));
                    spawnOffsets.Add(spawnOffset);
                }
            }

            // Spawn in random order
            while (spawnOffsets.Count > 0)
            {
                // Recalculate directions and start position since drone might have moved
                var     position     = ProjectileSpawnPoint.Transform.WorldMatrix.TranslationVector;
                Vector3 up           = Drone.Entity.Transform.WorldMatrix.Up;
                Vector3 aimDirection = Drone.HeadDirection;
                Vector3 right        = Vector3.Normalize(Vector3.Cross(up, aimDirection));

                // Retrieve spawn position for this missile based on the offsets
                int     targetPositionIndex = random.Next(0, spawnOffsets.Count - 1);
                Vector2 spawnOffset         = spawnOffsets[targetPositionIndex];
                Vector3 spawnPosition       = position + spawnOffset.X * right + spawnOffset.Y * up;
                spawnPosition += aimDirection * ((float)random.NextDouble() - 0.5f) * 0.1f;
                spawnOffsets.RemoveAt(targetPositionIndex);

                // Spawn rocket
                var projectileEntity = ProjectilePrefab.Instantiate().Single();
                var projectile       = projectileEntity.Get <Projectile>();
                projectile.Owner = Drone.Entity;

                projectiles.Add(projectile);
                projectileEntity.Transform.Position = spawnPosition;
                projectileEntity.Transform.Rotation = Quaternion.BetweenDirections(Vector3.UnitZ, Drone.HeadDirection);

                // Random Pitch/Roll (relative to shooting direction)
                Vector2 randomDeviation = new Vector2((float)random.NextDouble(), (float)random.NextDouble());
                randomDeviation.X  = randomDeviation.X * SpreadAngle.Radians; // Pitch
                randomDeviation.Y *= MathUtil.TwoPi;                          // Roll
                projectileEntity.Transform.Rotation = projectileEntity.Transform.Rotation * Quaternion.RotationAxis(right, randomDeviation.X) * Quaternion.RotationAxis(aimDirection, randomDeviation.Y);

                var rocket = (projectile as RocketProjectile);
                if (targetEntity != null)
                {
                    rocket?.SetTarget(targetEntity.Transform.WorldMatrix.TranslationVector);
                }
                else
                {
                    rocket?.SetTarget(position + aimDirection * ShootingRange);
                }

                Drone.SceneSystem.SceneInstance.RootScene.Entities.Add(projectile.Entity);

                // Set initial direction
                Vector3 initialRocketDirection = Vector3.Transform(Vector3.UnitZ, projectileEntity.Transform.Rotation);
                projectile.SetDirection(initialRocketDirection);

                shootSound.PlayAndForget();

                await Task.Delay(2 + random.Next(0, 8));
            }
        }