Beispiel #1
0
        private void sparks(Vector3 pos, Spark type, bool showLight, bool playSound)
        {
            for (int j = 0; j < 40; j++)
            {
                Vector3 offset = new Vector3((float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f);
                this.particles.AddParticle(pos + offset, offset);
            }

            if (showLight)
            {
                PointLight light;
                if (this.activeSparkLights < Propagator.maxSparkLights)
                {
                    light = this.sparkLights[this.activeSparkLights];
                    light.Enabled.Value = true;
                    this.activeSparkLights++;
                }
                else
                {
                    light = this.sparkLights[this.oldestSparkLight % this.activeSparkLights];
                    this.oldestSparkLight = (this.oldestSparkLight + 1) % Propagator.maxSparkLights;
                }

                light.Color.Value    = Vector3.One;
                light.Position.Value = pos;

                light.Attenuation.Value = type == Spark.Expander ? 10.0f : 5.0f;

                if (playSound)
                {
                    uint sound;
                    switch (type)
                    {
                    case Spark.Dangerous:
                        sound = AK.EVENTS.PLAY_RED_BURN;
                        break;

                    case Spark.Burn:
                        sound = AK.EVENTS.PLAY_ORANGE_BURN;
                        break;

                    default:
                        sound = AK.EVENTS.PLAY_BLUE_BURN;
                        break;
                    }
                    Sound.PostEvent(sound, pos);
                }
            }
        }
Beispiel #2
0
        public void Update(float dt)
        {
            this.raycastTimer += dt;
            if (this.raycastTimer > RaycastInterval)
            {
                this.Update();
            }

            if (!this.main.EditorEnabled)
            {
                this.thunderTimer -= dt;
                if (this.thunderTimer < 0)
                {
                    float volume = 0.6f + ((float)random.NextDouble() * 0.4f);
                    this.CurrentLightningColor.Value = Vector3.Zero;
                    Property <Vector3> skyboxColor;
                    if (this.skybox == null)
                    {
                        skyboxColor = new Property <Vector3>();                        // Dummy property
                    }
                    else
                    {
                        skyboxColor = this.skybox.Color;
                    }

                    this.Entity.Add(new Animation
                                    (
                                        new Animation.Set <bool>(this.LightningEnabled, true),
                                        new Animation.Parallel
                                        (
                                            new Animation.Vector3MoveTo(this.CurrentLightningColor, this.LightningColor.Value * volume, 0.2f),
                                            new Animation.Vector3MoveTo(skyboxColor, this.SkyboxColor.Value + this.LightningColor.Value * volume, 0.2f)
                                        ),
                                        new Animation.Parallel
                                        (
                                            new Animation.Vector3MoveTo(this.CurrentLightningColor, Vector3.Zero, 0.5f),
                                            new Animation.Vector3MoveTo(skyboxColor, this.SkyboxColor, 0.5f)
                                        ),
                                        new Animation.Set <bool>(this.LightningEnabled, false),
                                        new Animation.Delay((1.0f - volume) * this.ThunderMaxDelay),
                                        new Animation.Execute(delegate()
                    {
                        Sound.PostEvent(AK.EVENTS.PLAY_THUNDER, main.Camera.Position + Vector3.Normalize(new Vector3(2.0f * ((float)random.NextDouble() - 0.5f), 1.0f, 2.0f * ((float)random.NextDouble() - 0.5f))) * 1000.0f);
                    })
                                    ));
                    this.thunderTimer = this.ThunderIntervalMin + ((float)random.NextDouble() * (this.ThunderIntervalMax - this.ThunderIntervalMin));
                }
            }
        }
Beispiel #3
0
        public void Update(float dt)
        {
            if (this.Rolling)
            {
                this.rollKickTime += dt;

                Vector3 originalVelocity = this.LinearVelocity;
                this.LinearVelocity.Value = new Vector3(this.velocity.X, originalVelocity.Y, this.velocity.Z);

                if (this.rollKickTime > 0.1f && (this.rollKickTime > 1.0f || Vector3.Dot(originalVelocity - this.SupportVelocity, this.forward) < 0.1f))
                {
                    this.Rolling.Value       = false;
                    this.EnableWalking.Value = true;
                    if (!this.RollKickButton)
                    {
                        this.AllowUncrouch.Value = true;
                    }
                    this.LastRollKickEnded.Value = main.TotalTime;
                }
                else
                {
                    if (this.VoxelTools.BreakWalls(this.forward, this.right))
                    {
                        if (this.firstTimeBreak)
                        {
                            this.Rumble.Execute(0.5f);
                            Sound.PostEvent(AK.EVENTS.PLAY_WALL_BREAK, this.FloorPosition + this.forward * 2.0f);
                        }
                        this.firstTimeBreak = false;
                    }

                    if (this.shouldBuildFloor)
                    {
                        this.VoxelTools.BuildFloor(this.floorMap, this.floorCoordinate, this.forwardDir, this.rightDir);
                    }
                    else
                    {
                        this.checkShouldBuildFloor();
                    }
                }
            }
            else if (this.Kicking)
            {
                this.rollKickTime += dt;

                Vector3 originalVelocity = this.LinearVelocity;
                this.LinearVelocity.Value = new Vector3(this.velocity.X, originalVelocity.Y, this.velocity.Z);

                if (!this.IsSupported)
                {
                    if (this.sliding)
                    {
                        // We started out on the ground, but we kicked off an edge.
                        AkSoundEngine.PostEvent(AK.EVENTS.STOP_PLAYER_SLIDE_LOOP, this.Entity);
                    }
                    else if (originalVelocity.Y - this.SupportVelocity.Value.Y < FallDamage.DamageVelocity)
                    {
                        // We weren't supported when we started kicking. We're flying.
                        // Roll if we hit the ground while kicking mid-air
                        Vector3 playerPos           = this.FloorPosition + new Vector3(0, 0.5f, 0);
                        Voxel.GlobalRaycastResult r = this.raycastFloor();
                        if (r.Voxel != null)
                        {
                            this.StopKick();
                            this.Go(true);
                            return;
                        }
                    }
                }

                if (this.rollKickTime > 1.0f ||
                    (this.rollKickTime > 0.7f && (!this.RollKickButton || Vector3.Dot(originalVelocity - this.SupportVelocity, this.forward) < 0.1f)))
                {
                    this.StopKick();
                    return;
                }

                if (this.VoxelTools.BreakWalls(this.forward, this.right))
                {
                    if (this.firstTimeBreak)
                    {
                        this.Rumble.Execute(0.5f);
                        Sound.PostEvent(AK.EVENTS.PLAY_WALL_BREAK, this.FloorPosition + this.forward * 2.0f);
                    }
                    this.firstTimeBreak = false;
                }
                if (this.shouldBuildFloor)
                {
                    this.VoxelTools.BuildFloor(this.floorMap, this.floorCoordinate, this.forwardDir, this.rightDir);
                }
                else if (this.sliding)
                {
                    this.checkShouldBuildFloor();
                }
            }
        }
Beispiel #4
0
        private static void explode(Main main, Voxel map, Voxel.Coord coord, Vector3 pos, int radius, float physicsRadius)
        {
            float distanceToCamera = (main.Camera.Position.Value - pos).Length();

            // Kaboom
            Sound.PostEvent(distanceToCamera < physicsRadius * 1.5f ? AK.EVENTS.PLAY_EXPLOSION_CLOSE : AK.EVENTS.PLAY_EXPLOSION, pos);

            Entity lightEntity = Factory.Get <PointLightFactory>().CreateAndBind(main);

            lightEntity.Serialize = false;
            PointLight light = lightEntity.Get <PointLight>();

            light.Color.Value       = new Vector3(1.3f, 1.1f, 0.9f);
            light.Attenuation.Value = 20.0f;
            light.Position.Value    = pos;
            lightEntity.Add(new Animation
                            (
                                new Animation.FloatMoveTo(light.Attenuation, 0.0f, 1.0f),
                                new Animation.Execute(light.Delete)
                            ));
            main.Add(lightEntity);

            SmokeFactory smokeFactory = Factory.Get <SmokeFactory>();

            for (int i = 0; i < 5; i++)
            {
                Entity smoke = smokeFactory.CreateAndBind(main);
                smoke.Get <Transform>().Position.Value = pos;
                main.Add(smoke);
            }

            ParticleEmitter.Emit(main, "Smoke", pos, physicsRadius * 0.4f, 250);

            Entity player = PlayerFactory.Instance;

            if (player != null && player.Active)
            {
                player.Get <CameraController>().Shake.Execute(pos, 50.0f);
            }

            const float physicsImpulse         = 70.0f;
            const float minPlayerDamage        = 0.1f;
            const float playerDamageMultiplier = 2.0f;

            // Remove the cells
            BlockFactory blockFactory = Factory.Get <BlockFactory>();

            foreach (Voxel m in Voxel.ActiveVoxels.ToList())
            {
                List <Voxel.Coord> removals = new List <Voxel.Coord>();

                Voxel.Coord c           = m.GetCoordinate(pos);
                Vector3     relativePos = m.GetRelativePosition(c);

                Quaternion quat = m.Entity.Get <Transform>().Quaternion;

                for (Voxel.Coord x = c.Move(Direction.NegativeX, radius - 1); x.X < c.X + radius; x.X++)
                {
                    for (Voxel.Coord y = x.Move(Direction.NegativeY, radius - 1); y.Y < c.Y + radius; y.Y++)
                    {
                        for (Voxel.Coord z = y.Move(Direction.NegativeZ, radius - 1); z.Z < c.Z + radius; z.Z++)
                        {
                            Voxel.State s = m[z];
                            if (s.ID == 0 || s.Permanent)
                            {
                                continue;
                            }

                            Vector3 cellPos = m.GetRelativePosition(z);
                            if ((cellPos - relativePos).Length() < radius - 1)
                            {
                                removals.Add(z);
                                if (random.NextDouble() > 0.5)
                                {
                                    Entity    block          = blockFactory.CreateAndBind(main);
                                    Transform blockTransform = block.Get <Transform>();
                                    blockTransform.Position.Value   = m.GetAbsolutePosition(cellPos);
                                    blockTransform.Quaternion.Value = Quaternion.CreateFromYawPitchRoll(((float)random.NextDouble() - 0.5f) * 2.0f * (float)Math.PI, ((float)random.NextDouble() - 0.5f) * 2.0f * (float)Math.PI, ((float)random.NextDouble() - 0.5f) * 2.0f * (float)Math.PI);
                                    s.ApplyToBlock(block);
                                    main.Add(block);
                                }
                            }
                        }
                    }
                }
                if (removals.Count > 0)
                {
                    m.Empty(removals);
                    m.Regenerate();
                }
            }

            // Damage the player
            if (player != null && player.Active)
            {
                Vector3 toPlayer = player.Get <Transform>().Position - pos;
                float   d        = toPlayer.Length();
                if (d < physicsRadius)
                {
                    float attenuation = 1.0f;
                    if (d > 0)
                    {
                        Voxel.GlobalRaycast(pos, toPlayer / d, d, delegate(int x, Voxel.t c)
                        {
                            Voxel.State s = Voxel.States.All[c];
                            if (s.Permanent)
                            {
                                attenuation = 0.0f;
                                return(true);
                            }
                            else if (s.Hard)
                            {
                                attenuation -= 0.6f;
                            }
                            else
                            {
                                attenuation -= 0.35f;
                            }
                            return(false);
                        });
                        attenuation = Math.Max(0, attenuation);
                    }
                    player.Get <Agent>().Damage.Execute(attenuation * (minPlayerDamage + (1.0f - (d / physicsRadius)) * playerDamageMultiplier));
                }
            }

            // Apply impulse to dynamic maps
            foreach (Voxel m in Voxel.ActiveVoxels)
            {
                DynamicVoxel dm = m as DynamicVoxel;
                if (dm == null)
                {
                    continue;
                }

                Vector3 toMap         = dm.Transform.Value.Translation - pos;
                float   distanceToMap = toMap.Length();
                toMap /= distanceToMap;

                toMap *= Math.Max(0.0f, 1.0f - (distanceToMap / physicsRadius)) * Math.Min(200.0f, dm.PhysicsEntity.Mass) * physicsImpulse;

                dm.PhysicsEntity.ApplyImpulse(dm.Transform.Value.Translation + new Vector3(((float)random.NextDouble() - 0.5f) * 2.0f, ((float)random.NextDouble() - 0.5f) * 2.0f, ((float)random.NextDouble() - 0.5f) * 2.0f), toMap);
            }

            // Apply impulse to physics blocks
            foreach (Entity b in main.Get("Block"))
            {
                PhysicsBlock block         = b.Get <PhysicsBlock>();
                Vector3      fromExplosion = b.Get <Transform>().Position.Value - pos;
                float        distance      = fromExplosion.Length();
                if (distance > 0.0f && distance < physicsRadius)
                {
                    float blend = 1.0f - (distance / physicsRadius);
                    block.Box.LinearVelocity  += fromExplosion * blend * 10.0f / distance;
                    block.Box.AngularVelocity += new Vector3(((float)random.NextDouble() - 0.5f) * 2.0f, ((float)random.NextDouble() - 0.5f) * 2.0f, ((float)random.NextDouble() - 0.5f) * 2.0f) * blend;
                }
            }
        }
Beispiel #5
0
        public override void Awake()
        {
            base.Awake();

            this.blockFactory = Factory.Get <EffectBlockFactory>();

            this.EnabledWhenPaused = false;

            if (main.EditorEnabled)
            {
                this.BlockQueue.Clear();
            }

            this.particles = ParticleSystem.Get(main, "WhiteShatter");

            for (int i = 0; i < maxSparkLights; i++)
            {
                PointLight light = new PointLight();
                light.Serialize     = false;
                light.Color.Value   = new Vector3(1.0f);
                light.Enabled.Value = false;
                this.Entity.Add(light);
                this.sparkLights.Add(light);
            }

            if (!this.main.EditorEnabled)
            {
                this.Add(new CommandBinding <Voxel, IEnumerable <Voxel.Coord>, Voxel>(Voxel.GlobalCellsFilled, delegate(Voxel map, IEnumerable <Voxel.Coord> coords, Voxel transferredFromMap)
                {
                    foreach (Voxel.Coord c in coords)
                    {
                        Voxel.t id = c.Data.ID;
                        if (id == Voxel.t.Powered || id == Voxel.t.PoweredSwitch || id == Voxel.t.HardPowered || id == Voxel.t.Infected || id == Voxel.t.HardInfected ||
                            (transferredFromMap == null && (id == Voxel.t.Blue || id == Voxel.t.Neutral || id == Voxel.t.Hard)))
                        {
                            Voxel.Coord newCoord = c;
                            newCoord.Data        = Voxel.States.Empty;
                            int generation;
                            EffectBlock.Entry generationsKey = new EffectBlock.Entry {
                                Voxel = map, Coordinate = newCoord
                            };
                            if (this.generations.TryGetValue(generationsKey, out generation))
                            {
                                this.generations.Remove(generationsKey);
                            }
                            if (!this.isInQueue(map.Entity, newCoord, false))
                            {
                                this.BlockQueue.Add(new ScheduledBlock
                                {
                                    Voxel      = map.Entity,
                                    Coordinate = newCoord,
                                    Time       = propagateDelay,
                                    Generation = generation,
                                });
                            }
                        }
                    }
                }));

                this.Add(new CommandBinding <Voxel, IEnumerable <Voxel.Coord>, Voxel>(Voxel.GlobalCellsEmptied, delegate(Voxel map, IEnumerable <Voxel.Coord> coords, Voxel transferringToNewMap)
                {
                    foreach (Voxel.Coord coord in coords)
                    {
                        Voxel.t id = coord.Data.ID;
                        if (id == Voxel.t.Powered || id == Voxel.t.PoweredSwitch || id == Voxel.t.HardPowered || id == Voxel.t.PermanentPowered)
                        {
                            this.removedPoweredCoords.Add(coord);
                        }
                        if (transferringToNewMap != null)
                        {
                            continue;
                        }

                        if (id == Voxel.t.Critical)                         // Critical. Explodes when destroyed.
                        {
                            Explosion.Explode(main, map, coord);
                        }
                        else if (id == Voxel.t.Powered || id == Voxel.t.Blue || id == Voxel.t.Neutral || id == Voxel.t.Infected || id == Voxel.t.Floater)
                        {
                            int generation;
                            Voxel.Coord c = coord;
                            c.Data        = Voxel.States.Empty;
                            EffectBlock.Entry generationKey = new EffectBlock.Entry {
                                Voxel = map, Coordinate = c
                            };
                            if (this.generations.TryGetValue(generationKey, out generation))
                            {
                                this.generations.Remove(generationKey);
                            }

                            if (id == Voxel.t.Floater)
                            {
                                Entity blockEntity      = this.blockFactory.CreateAndBind(main);
                                EffectBlock effectBlock = blockEntity.Get <EffectBlock>();
                                coord.Data.ApplyToEffectBlock(blockEntity.Get <ModelInstance>());
                                effectBlock.Delay            = 4.0f;
                                effectBlock.Offset.Value     = map.GetRelativePosition(coord);
                                effectBlock.StartPosition    = map.GetAbsolutePosition(coord) + new Vector3(2.5f, 5.0f, 2.5f);
                                effectBlock.StartOrientation = Quaternion.CreateFromYawPitchRoll(1.0f, 1.0f, 0);
                                effectBlock.TotalLifetime    = 0.5f;
                                effectBlock.Setup(map.Entity, coord, coord.Data.ID);
                                main.Add(blockEntity);
                            }

                            if (generation == 0)
                            {
                                if (!this.isInQueue(map.Entity, coord, true))
                                {
                                    this.BlockQueue.Add(new ScheduledBlock
                                    {
                                        Voxel      = map.Entity,
                                        Coordinate = coord,
                                        Time       = propagateDelay,
                                        Removing   = true,
                                    });
                                }
                            }
                            else if (generation < maxGenerations)
                            {
                                Direction down = map.GetRelativeDirection(Direction.NegativeY);
                                for (int i = 0; i < 6; i++)
                                {
                                    Direction dir        = DirectionExtensions.Directions[i];
                                    Voxel.Coord adjacent = coord.Move(dir);
                                    if (!coords.Contains(adjacent))
                                    {
                                        Voxel.t adjacentID     = map[adjacent].ID;
                                        bool adjacentIsFloater = adjacentID == Voxel.t.Floater;
                                        if (dir != down || adjacentIsFloater)
                                        {
                                            if (adjacentID == Voxel.t.Powered || adjacentID == Voxel.t.Blue || adjacentID == Voxel.t.Neutral || adjacentID == Voxel.t.Infected || adjacentIsFloater)
                                            {
                                                if (!this.isInQueue(map.Entity, adjacent, true))
                                                {
                                                    this.BlockQueue.Add(new ScheduledBlock
                                                    {
                                                        Voxel      = map.Entity,
                                                        Coordinate = adjacent,
                                                        Time       = propagateDelay,
                                                        Removing   = true,
                                                        Generation = generation + 1,
                                                    });
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                        else if (id == Voxel.t.White || id == Voxel.t.Glass)                         // Shatter effects.
                        {
                            ParticleSystem shatter = ParticleSystem.Get(main, "WhiteShatter");
                            Vector3 pos            = map.GetAbsolutePosition(coord);
                            for (int i = 0; i < 50; i++)
                            {
                                Vector3 offset = new Vector3((float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f);
                                shatter.AddParticle(pos + offset, offset);
                            }
                            float time = this.main.TotalTime;
                            if (time - this.lastShatterSound > 0.3f)
                            {
                                this.lastShatterSound = time;
                                Sound.PostEvent(AK.EVENTS.PLAY_WHITE_SHATTER, pos);
                            }
                        }
                    }

                    if (this.removedPoweredCoords.Count > 0)
                    {
                        IEnumerable <IEnumerable <Voxel.Box> > poweredIslands = map.GetAdjacentIslands(this.removedPoweredCoords, x => x.ID == Voxel.t.Powered || x.ID == Voxel.t.HardPowered, x => x == Voxel.States.PermanentPowered || x == Voxel.States.PoweredSwitch);
                        List <Voxel.Coord> poweredCoords = poweredIslands.SelectMany(x => x).SelectMany(x => x.GetCoords()).ToList();
                        if (poweredCoords.Count > 0)
                        {
                            lock (map.MutationLock)
                            {
                                map.Empty(poweredCoords, true, true, map, false);
                                for (int i = 0; i < poweredCoords.Count; i++)
                                {
                                    Voxel.Coord coord = poweredCoords[i];
                                    if (coord.Data.ID == Voxel.t.HardPowered)
                                    {
                                        map.Fill(coord, Voxel.States.Hard, true, map);
                                    }
                                    else
                                    {
                                        map.Fill(coord, Voxel.States.Blue, true, map);
                                    }
                                }
                            }
                            this.toRegenerate.Add(map);
                        }
                        this.removedPoweredCoords.Clear();
                    }
                }));
            }
        }
Beispiel #6
0
        public void Update(float dt)
        {
            if (this.TargetVoxel.Target == null || !this.TargetVoxel.Target.Active)
            {
                this.Delete.Execute();
                return;
            }

            this.Lifetime += dt;

            if (this.Lifetime < this.Delay)
            {
                return;
            }

            float blend = (this.Lifetime - this.Delay) / this.TotalLifetime;

            Voxel m = this.TargetVoxel.Target.Get <Voxel>();

            Matrix finalOrientation = m.Transform;

            finalOrientation.Translation = Vector3.Zero;
            Quaternion finalQuat = Quaternion.CreateFromRotationMatrix(finalOrientation);

            Vector3 finalPosition = m.GetAbsolutePosition(this.Coord);

            if (blend > 1.0f)
            {
                if (this.StateId != Voxel.t.Empty)
                {
                    Voxel.Coord c = this.Coord;

                    bool blue = this.StateId == Voxel.t.Blue;
                    bool foundAdjacentCell = false;
                    bool foundConflict     = false;
                    if (this.CheckAdjacent)
                    {
                        foreach (Direction dir in DirectionExtensions.Directions)
                        {
                            Voxel.Coord adjacent   = c.Move(dir);
                            Voxel.t     adjacentID = m[adjacent].ID;
                            if (adjacentID != Voxel.t.Empty)
                            {
                                if (blue && (adjacentID == Voxel.t.Infected || adjacentID == Voxel.t.HardInfected || adjacentID == Voxel.t.Slider || adjacentID == Voxel.t.SliderPowered || adjacentID == Voxel.t.SocketWhite || adjacentID == Voxel.t.SocketBlue || adjacentID == Voxel.t.SocketYellow))
                                {
                                    foundConflict = true;
                                }
                                else
                                {
                                    foundAdjacentCell = true;
                                    if (blue)
                                    {
                                        if (adjacentID == Voxel.t.Reset)
                                        {
                                            this.StateId = Voxel.t.Neutral;
                                            break;
                                        }
                                        else if (adjacentID == Voxel.t.Powered || adjacentID == Voxel.t.PermanentPowered || adjacentID == Voxel.t.PoweredSwitch || adjacentID == Voxel.t.HardPowered)
                                        {
                                            this.StateId = Voxel.t.Powered;
                                            break;
                                        }
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        foundAdjacentCell = true;
                    }

                    if (foundAdjacentCell)
                    {
                        Vector3 absolutePos = m.GetAbsolutePosition(c);

                        if (blue && !Zone.CanBuild(absolutePos))
                        {
                            foundConflict = true;
                        }

                        if (!foundConflict)
                        {
                            bool isDynamic = m.GetType() == typeof(DynamicVoxel);
                            foreach (Voxel m2 in Voxel.ActivePhysicsVoxels)
                            {
                                bool atLeastOneDynamic = isDynamic || m2.GetType() == typeof(DynamicVoxel);
                                if (m2 != m && atLeastOneDynamic && m2[absolutePos].ID != 0)
                                {
                                    foundConflict = true;
                                    break;
                                }
                            }
                        }

                        if (!foundConflict)
                        {
                            Voxel.State state = m[this.Coord];
                            if (state.Permanent || state.Hard || state.ID == this.StateId || (blue && state == Voxel.States.Powered))
                            {
                                foundConflict = true;
                            }
                            else
                            {
                                if (state.ID != 0)
                                {
                                    m.Empty(this.Coord);
                                }
                                m.Fill(this.Coord, Voxel.States.All[this.StateId]);
                                m.Regenerate();
                                if (this.main.TotalTime - EffectBlock.lastSound > 0.15f)
                                {
                                    EffectBlock.lastSound = this.main.TotalTime;
                                    Sound.PostEvent(this.StateId == Voxel.t.Floater ? AK.EVENTS.PLAY_FLOATER_BUILD : AK.EVENTS.PLAY_BLOCK_BUILD, absolutePos);
                                }
                                this.Entity.Delete.Execute();
                                return;
                            }
                        }
                    }

                    // For one reason or another, we can't fill the cell
                    // Animate nicely into oblivion
                    this.StateId = Voxel.t.Empty;
                }
                else
                {
                    // For one reason or another, we can't fill the cell
                    // Animate nicely into oblivion
                    if (blend > 2.0f)
                    {
                        this.Delete.Execute();
                    }
                    else
                    {
                        Matrix result = Matrix.CreateFromQuaternion(finalQuat);
                        float  scale  = 2.0f - blend;
                        result.Right        *= scale;
                        result.Up           *= scale;
                        result.Forward      *= scale;
                        result.Translation   = finalPosition;
                        this.Transform.Value = result;
                    }
                }
            }
            else
            {
                float scale;
                if (this.DoScale)
                {
                    scale = blend;
                }
                else
                {
                    scale = 1.0f;
                }

                float distance = (finalPosition - this.StartPosition).Length() * 0.1f * Math.Max(0.0f, 0.5f - Math.Abs(blend - 0.5f));

                Matrix result = Matrix.CreateFromQuaternion(Quaternion.Lerp(this.StartOrientation, finalQuat, blend));
                result.Right        *= scale;
                result.Up           *= scale;
                result.Forward      *= scale;
                result.Translation   = Vector3.Lerp(this.StartPosition, finalPosition, blend) + new Vector3((float)Math.Sin(blend * Math.PI) * distance);
                this.Transform.Value = result;
            }
        }
Beispiel #7
0
        public override void Awake()
        {
            base.Awake();
            this.EnabledWhenPaused = false;
            this.Serialize         = false;

            this.Footstep.Action = delegate()
            {
                if (this.SoundEnabled && this.main.TotalTime - this.lastFootstepSound > footstepSoundInterval)
                {
                    AkSoundEngine.PostEvent(AK.EVENTS.FOOTSTEP_PLAY, this.Entity);
                    this.lastFootstepSound = this.main.TotalTime;
                }
            };

            this.Add(new CommandBinding <Voxel, Voxel.Coord, Direction>(this.WalkedOn, delegate(Voxel map, Voxel.Coord coord, Direction dir)
            {
                Voxel.State state = map[coord];

                if (state != Voxel.States.Empty)
                {
                    AkSoundEngine.SetSwitch(AK.SWITCHES.FOOTSTEP_MATERIAL.GROUP, state.FootstepSwitch, this.Entity);

                    if (this.WallRunState.Value == WallRun.State.None)
                    {
                        if (map.GetAbsoluteDirection(dir) == Direction.NegativeY && !this.IsSwimming)
                        {
                            this.walkedOnCount++;
                            if (this.walkedOnCount >= 2)
                            {
                                // Every few tiles, save off the location for the auto-respawn system
                                coord.Data = null;
                                this.RespawnLocations.Add(new RespawnLocation
                                {
                                    Coordinate       = coord,
                                    Map              = map.Entity,
                                    Rotation         = this.Rotation,
                                    OriginalPosition = map.GetAbsolutePosition(coord),
                                });
                                while (this.RespawnLocations.Length > Spawner.RespawnMemoryLength)
                                {
                                    this.RespawnLocations.RemoveAt(0);
                                }
                                this.walkedOnCount = 0;
                            }
                        }
                    }
                }

                Voxel.t id = state.ID;
                if (id == Voxel.t.Neutral)
                {
                    map.Empty(coord, false, true, map);
                    bool isPowered = false;
                    for (int i = 0; i < 6; i++)
                    {
                        Voxel.Coord adjacentCoord = coord.Move(DirectionExtensions.Directions[i]);
                        Voxel.t adjacentId        = map[coord].ID;
                        if (adjacentId == Voxel.t.Powered || adjacentId == Voxel.t.PermanentPowered || adjacentId == Voxel.t.PoweredSwitch || adjacentId == Voxel.t.HardPowered)
                        {
                            isPowered = true;
                            break;
                        }
                    }
                    map.Fill(coord, isPowered ? Voxel.States.Powered : Voxel.States.Blue);
                    map.Regenerate();
                    WorldFactory.Instance.Get <Propagator>().Sparks(map.GetAbsolutePosition(coord), Propagator.Spark.Normal);
                }
                else if (id == Voxel.t.Reset)
                {
                    bool regenerate = false;

                    Queue <Voxel.Coord> queue = new Queue <Voxel.Coord>();
                    queue.Enqueue(coord);
                    Voxel.CoordSetCache.Add(coord);
                    while (queue.Count > 0)
                    {
                        Voxel.Coord c = queue.Dequeue();
                        for (int i = 0; i < 6; i++)
                        {
                            Voxel.Coord adjacentCoord = c.Move(DirectionExtensions.Directions[i]);
                            if (!Voxel.CoordSetCache.Contains(adjacentCoord))
                            {
                                Voxel.CoordSetCache.Add(adjacentCoord);
                                Voxel.t adjacentID = map[adjacentCoord].ID;
                                if (adjacentID == Voxel.t.Reset || adjacentID == Voxel.t.Hard)
                                {
                                    queue.Enqueue(adjacentCoord);
                                }
                                else if (adjacentID == Voxel.t.Infected || adjacentID == Voxel.t.Blue || adjacentID == Voxel.t.Powered)
                                {
                                    map.Empty(adjacentCoord, false, true, map);
                                    map.Fill(adjacentCoord, Voxel.States.Neutral);
                                    regenerate = true;
                                }
                                else if (adjacentID == Voxel.t.HardPowered || adjacentID == Voxel.t.HardInfected)
                                {
                                    map.Empty(adjacentCoord, false, true, map);
                                    map.Fill(adjacentCoord, Voxel.States.Hard);
                                    regenerate = true;
                                }
                            }
                        }
                    }
                    Voxel.CoordSetCache.Clear();
                    if (regenerate)
                    {
                        map.Regenerate();
                    }
                }

                // Lava. Damage the player character if it steps on lava.
                bool isInfected = id == Voxel.t.Infected || id == Voxel.t.HardInfected;
                if (isInfected)
                {
                    this.Damage.Execute(0.2f);
                }
                else if (id == Voxel.t.Floater)
                {
                    // Floater. Delete the block after a delay.
                    Vector3 pos = map.GetAbsolutePosition(coord);
                    ParticleEmitter.Emit(main, "Smoke", pos, 1.0f, 10);
                    Sound.PostEvent(AK.EVENTS.PLAY_CRUMBLE, pos);
                    WorldFactory.Instance.Add(new Animation
                                              (
                                                  new Animation.Delay(0.5f),
                                                  new Animation.Execute(delegate()
                    {
                        if (map[coord].ID == Voxel.t.Floater)
                        {
                            map.Empty(coord);
                            map.Regenerate();
                        }
                    })
                                              ));
                }

                this.infectedDamage = isInfected;
            }));
        }
Beispiel #8
0
        private void fall()
        {
            if (this.TimeUntilRebuild.Value > 0 || this.TimeUntilRebuildComplete.Value > 0)
            {
                return;
            }

            Entity targetVoxel = this.TargetVoxel.Value.Target;

            if (targetVoxel == null || !targetVoxel.Active)
            {
                return;
            }

            // Disable the cell-emptied notification.
            // This way, we won't think that the base has been destroyed by the player.
            // We are not in fact dying, we're just destroying the base so we can fall over.
            this.Base.EnableCellEmptyBinding = false;

            Voxel m = targetVoxel.Get <Voxel>();

            m.Empty(this.Base.BaseBoxes.SelectMany(x => x.GetCoords()));
            Vector3 basePosition = Vector3.Zero;
            int     baseSize     = 0;

            foreach (Voxel.Coord c in this.Base.BaseBoxes.SelectMany(x => x.GetCoords()))
            {
                ParticleSystem shatter = ParticleSystem.Get(main, "InfectedShatter");
                Vector3        pos     = m.GetAbsolutePosition(c);
                for (int i = 0; i < 50; i++)
                {
                    Vector3 offset = new Vector3((float)random.NextDouble() - 0.5f, (float)random.NextDouble() - 0.5f, (float)random.NextDouble() - 0.5f);
                    shatter.AddParticle(pos + offset, offset);
                }
                basePosition += pos;
                baseSize++;
            }
            basePosition /= (float)baseSize;
            Sound.PostEvent(AK.EVENTS.PLAY_TOWER_FALL, basePosition);

            m.Regenerate(delegate(List <DynamicVoxel> spawnedMaps)
            {
                if (spawnedMaps.Count == 0)
                {
                    this.Delete.Execute();
                }
                else
                {
                    Vector3 playerPos = PlayerFactory.Instance.Get <Transform>().Position;
                    playerPos        += PlayerFactory.Instance.Get <Player>().Character.LinearVelocity.Value * 0.65f;
                    foreach (DynamicVoxel newMap in spawnedMaps)
                    {
                        newMap.Dangerous.Value = true;
                        Vector3 toPlayer       = playerPos - newMap.PhysicsEntity.Position;
                        toPlayer.Normalize();
                        if (Math.Abs(toPlayer.Y) < 0.9f)
                        {
                            toPlayer *= 25.0f * newMap.PhysicsEntity.Mass;

                            Vector3 positionAtPlayerHeight = newMap.PhysicsEntity.Position;
                            Vector3 impulseAtBase          = toPlayer * -0.75f;
                            impulseAtBase.Y          = 0.0f;
                            positionAtPlayerHeight.Y = playerPos.Y;
                            newMap.PhysicsEntity.ApplyImpulse(ref positionAtPlayerHeight, ref impulseAtBase);

                            newMap.PhysicsEntity.ApplyLinearImpulse(ref toPlayer);
                        }
                        newMap.PhysicsEntity.Material.KineticFriction = 1.0f;
                        newMap.PhysicsEntity.Material.StaticFriction  = 1.0f;
                        this.DynamicVoxels.Add(newMap.Entity);
                    }
                }
            });

            this.TimeUntilRebuild.Value = RebuildDelay;
        }