예제 #1
0
 public void Setup(Entity map, Voxel.Coord c, Voxel.t s)
 {
     this.TargetVoxel = map;
     this.Coord       = c;
     this.StateId     = s;
     this.addEntry();
 }
예제 #2
0
파일: Slider.cs 프로젝트: schmittens/Lemma
        private void updateMaterial()
        {
            if (!this.main.EditorEnabled)
            {
                DynamicVoxel map = this.Entity.Get <DynamicVoxel>();
                if (map != null)
                {
                    bool active = this.Locked && (!this.Servo || (this.Servo && this.Goal.Value != this.Minimum.Value));

                    Voxel.State desired   = active ? Voxel.States.SliderPowered : Voxel.States.Slider;
                    Voxel.t     currentID = map[0, 0, 0].ID;
                    if (currentID != desired.ID & (currentID == Voxel.t.Slider || currentID == Voxel.t.SliderPowered))
                    {
                        List <Voxel.Coord> coords = map.GetContiguousByType(new[] { map.GetBox(0, 0, 0) }).SelectMany(x => x.GetCoords()).ToList();
                        map.Empty(coords, true, true, null, false);
                        foreach (Voxel.Coord c in coords)
                        {
                            map.Fill(c, desired);
                        }
                        map.Regenerate();
                    }
                    map.PhysicsEntity.ActivityInformation.Activate();
                }
            }
        }
예제 #3
0
 private void checkShouldBuildFloor()
 {
     if (this.EnableEnhancedRollSlide)
     {
         Voxel.GlobalRaycastResult floorRaycast = this.raycastFloor();
         if (floorRaycast.Voxel != null && floorRaycast.Voxel.Entity.Type != "Bouncer")
         {
             Voxel.t t = floorRaycast.Voxel[floorRaycast.Coordinate.Value].ID;
             if (t != Voxel.t.Blue && t != Voxel.t.Powered && t != Voxel.t.Slider && t != Voxel.t.SliderPowered)
             {
                 this.floorCoordinate  = floorRaycast.Coordinate.Value;
                 this.shouldBuildFloor = true;
                 if (this.Kicking)
                 {
                     this.sliding = true;
                     AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PLAYER_SLIDE_LOOP, this.Entity);
                 }
             }
         }
     }
 }
예제 #4
0
        public override void Bind(Entity entity, Main main, bool creating = false)
        {
            Transform transform = entity.GetOrCreate <Transform>("Transform");

            this.SetMain(entity, main);

            VoxelAttachable attachable = VoxelAttachable.MakeAttachable(entity, main, true, false);

            attachable.Offset.Value  = 1;
            attachable.Enabled.Value = true;

            PowerBlockSocket socket = entity.GetOrCreate <PowerBlockSocket>("PowerBlockSocket");

            socket.Add(new Binding <Voxel.Coord>(socket.Coord, attachable.Coord));
            socket.Add(new Binding <Entity.Handle>(socket.AttachedVoxel, attachable.AttachedVoxel));

            const float maxLightAttenuation = 15.0f;
            PointLight  light = entity.Create <PointLight>();

            light.Attenuation.Value = maxLightAttenuation;
            light.Add(new Binding <Vector3>(light.Position, transform.Position));
            light.Add(new Binding <Vector3, Voxel.t>(light.Color, delegate(Voxel.t t)
            {
                switch (t)
                {
                case Voxel.t.GlowBlue:
                    return(new Vector3(0.8f, 0.9f, 1.2f));

                case Voxel.t.GlowYellow:
                    return(new Vector3(1.2f, 1.2f, 0.8f));

                default:
                    return(Vector3.One);
                }
            }, socket.Type));
            light.Add(new Binding <bool>(light.Enabled, socket.Powered));

            PointLight animationLight = entity.Create <PointLight>();

            animationLight.Add(new Binding <Vector3>(animationLight.Position, light.Position));
            animationLight.Add(new Binding <Vector3>(animationLight.Color, light.Color));
            animationLight.Enabled.Value = false;

            PlayerTrigger trigger = entity.GetOrCreate <PlayerTrigger>("PlayerTrigger");

            trigger.Radius.Value = 7;
            trigger.Add(new Binding <Vector3>(trigger.Position, transform.Position));
            const float minimumChangeTime = 1.5f;
            float       lastChange        = -minimumChangeTime;

            trigger.Add(new CommandBinding(trigger.PlayerEntered, delegate()
            {
                if (main.TotalTime - lastChange > minimumChangeTime)
                {
                    BlockCloud cloud = PlayerFactory.Instance.Get <BlockCloud>();

                    bool changed    = false;
                    Voxel sockVoxel = attachable.AttachedVoxel.Value.Target.Get <Voxel>();
                    if (!socket.Powered && cloud.Type.Value == socket.Type.Value)
                    {
                        // Plug in to the socket
                        List <Voxel.Coord> coords = new List <Voxel.Coord>();
                        Queue <Voxel.Coord> queue = new Queue <Voxel.Coord>();
                        queue.Enqueue(sockVoxel.GetCoordinate(transform.Position));
                        while (queue.Count > 0)
                        {
                            Voxel.Coord c = queue.Dequeue();
                            coords.Add(c);
                            if (coords.Count >= cloud.Blocks.Length)
                            {
                                break;
                            }

                            Voxel.CoordDictionaryCache[c] = true;
                            foreach (Direction adjacentDirection in DirectionExtensions.Directions)
                            {
                                Voxel.Coord adjacentCoord = c.Move(adjacentDirection);
                                if (!Voxel.CoordDictionaryCache.ContainsKey(adjacentCoord))
                                {
                                    Voxel.t adjacentID = sockVoxel[adjacentCoord].ID;
                                    if (adjacentID == Voxel.t.Empty)
                                    {
                                        queue.Enqueue(adjacentCoord);
                                    }
                                }
                            }
                        }
                        Voxel.CoordDictionaryCache.Clear();

                        EffectBlockFactory factory = Factory.Get <EffectBlockFactory>();
                        int i = 0;
                        foreach (Entity block in cloud.Blocks)
                        {
                            Entity effectBlockEntity = factory.CreateAndBind(main);
                            Voxel.States.All[cloud.Type].ApplyToEffectBlock(effectBlockEntity.Get <ModelInstance>());
                            EffectBlock effectBlock      = effectBlockEntity.Get <EffectBlock>();
                            effectBlock.DoScale          = false;
                            Transform blockTransform     = block.Get <Transform>();
                            effectBlock.StartPosition    = blockTransform.Position;
                            effectBlock.StartOrientation = blockTransform.Quaternion;
                            effectBlock.TotalLifetime    = (i + 1) * 0.04f;
                            effectBlock.Setup(sockVoxel.Entity, coords[i], cloud.Type);
                            main.Add(effectBlockEntity);
                            block.Delete.Execute();
                            i++;
                        }
                        cloud.Blocks.Clear();
                        cloud.Type.Value     = Voxel.t.Empty;
                        socket.Powered.Value = true;
                        changed = true;
                    }
                    else if (socket.Powered && cloud.Type.Value == Voxel.t.Empty && !socket.PowerOnOnly)
                    {
                        // Pull blocks out of the socket
                        SceneryBlockFactory factory = Factory.Get <SceneryBlockFactory>();
                        Quaternion quat             = Quaternion.CreateFromRotationMatrix(sockVoxel.Transform);
                        cloud.Type.Value            = socket.Type;
                        List <Voxel.Coord> coords   = sockVoxel.GetContiguousByType(new[] { sockVoxel.GetBox(transform.Position) }).SelectMany(x => x.GetCoords()).ToList();
                        sockVoxel.Empty(coords, true);
                        sockVoxel.Regenerate();
                        ParticleSystem particles = ParticleSystem.Get(main, "WhiteShatter");
                        foreach (Voxel.Coord c in coords)
                        {
                            Vector3 pos = sockVoxel.GetAbsolutePosition(c);
                            for (int j = 0; j < 20; j++)
                            {
                                Vector3 offset = new Vector3((float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f, (float)this.random.NextDouble() - 0.5f);
                                particles.AddParticle(pos + offset, offset);
                            }
                            Entity block                    = factory.CreateAndBind(main);
                            Transform blockTransform        = block.Get <Transform>();
                            blockTransform.Position.Value   = pos;
                            blockTransform.Quaternion.Value = quat;
                            SceneryBlock sceneryBlock       = block.Get <SceneryBlock>();
                            sceneryBlock.Type.Value         = socket.Type;
                            sceneryBlock.Scale.Value        = 0.5f;
                            cloud.Blocks.Add(block);
                            main.Add(block);
                        }
                        socket.Powered.Value = false;
                        changed = true;
                    }

                    if (changed)
                    {
                        lastChange = main.TotalTime;
                        animationLight.Enabled.Value     = true;
                        animationLight.Attenuation.Value = 0.0f;
                        entity.Add(new Animation
                                   (
                                       new Animation.FloatMoveTo(animationLight.Attenuation, maxLightAttenuation, 0.25f),
                                       new Animation.FloatMoveTo(animationLight.Attenuation, 0.0f, 2.0f),
                                       new Animation.Set <bool>(animationLight.Enabled, false)
                                   ));
                    }
                }
            }));

            entity.Add("Type", socket.Type);
            entity.Add("Powered", socket.Powered, new PropertyEntry.EditorData {
                Readonly = true
            });
            entity.Add("PowerOnOnly", socket.PowerOnOnly);
            entity.Add("OnPowerOn", socket.OnPowerOn);
            entity.Add("OnPowerOff", socket.OnPowerOff);
        }
예제 #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.Blue || id == Voxel.t.Powered || id == Voxel.t.PoweredSwitch || id == Voxel.t.Infected || id == Voxel.t.Neutral || id == Voxel.t.HardPowered || id == Voxel.t.Hard || id == Voxel.t.HardInfected)
                        {
                            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.HardInfected)                         // Infected. Shatter effects.
                        {
                            ParticleSystem shatter = ParticleSystem.Get(main, "InfectedShatter");
                            Vector3 pos            = map.GetAbsolutePosition(coord);
                            AkSoundEngine.PostEvent(AK.EVENTS.PLAY_INFECTED_CRITICAL_SHATTER, pos);
                            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);
                            }
                        }
                        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;
                                AkSoundEngine.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, false);
                                    }
                                    else
                                    {
                                        map.Fill(coord, Voxel.States.Blue, false);
                                    }
                                }
                            }
                            this.toRegenerate.Add(map);
                        }
                        this.removedPoweredCoords.Clear();
                    }
                }));
            }
        }
예제 #6
0
        public void Update(float dt)
        {
            float sparkLightFade = sparkLightBrightness * dt / sparkLightFadeTime;

            for (int i = 0; i < activeSparkLights; i++)
            {
                PointLight light = this.sparkLights[i];
                float      a     = light.Color.Value.X - sparkLightFade;
                if (a < 0.0f)
                {
                    light.Enabled.Value = false;
                    PointLight swap = this.sparkLights[activeSparkLights - 1];
                    this.sparkLights[i] = swap;
                    this.sparkLights[activeSparkLights - 1] = light;
                    activeSparkLights--;
                    oldestSparkLight = activeSparkLights;
                }
                else
                {
                    light.Color.Value = new Vector3(a);
                }
            }

            for (int i = 0; i < this.BlockQueue.Length; i++)
            {
                ScheduledBlock entry = this.BlockQueue[i];
                entry.Time -= dt;
                if (entry.Time < 0.0f)
                {
                    this.BlockQueue.RemoveAt(i);
                    i--;

                    Entity mapEntity = entry.Voxel.Target;
                    if (mapEntity != null && mapEntity.Active)
                    {
                        Voxel       map = mapEntity.Get <Voxel>();
                        Voxel.Coord c   = entry.Coordinate;
                        Voxel.t     id  = map[c].ID;

                        bool regenerate = false;

                        if (entry.Removing)
                        {
                            if (entry.Generation == 0 && id == 0)
                            {
                                Direction down = map.GetRelativeDirection(Direction.NegativeY);
                                for (int j = 0; j < 6; j++)
                                {
                                    Direction   dir               = DirectionExtensions.Directions[j];
                                    Voxel.Coord adjacent          = c.Move(dir);
                                    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 = 1,
                                                });
                                            }
                                        }
                                    }
                                }
                            }
                            else if (entry.Generation > 0 && (id == Voxel.t.Blue || id == Voxel.t.Infected || id == Voxel.t.Powered || id == Voxel.t.PermanentPowered || id == Voxel.t.HardPowered || id == Voxel.t.PoweredSwitch || id == Voxel.t.Neutral || id == Voxel.t.Floater))
                            {
                                this.generations[new EffectBlock.Entry {
                                                     Voxel = map, Coordinate = c
                                                 }] = entry.Generation;
                                map.Empty(c);
                                this.SparksLowPriority(map.GetAbsolutePosition(c), Spark.Burn);
                                regenerate = true;
                            }
                        }
                        else if (id == Voxel.t.Blue)
                        {
                            for (int j = 0; j < 6; j++)
                            {
                                Direction   dir        = DirectionExtensions.Directions[j];
                                Voxel.Coord adjacent   = c.Move(dir);
                                Voxel.t     adjacentID = map[adjacent].ID;

                                if (adjacentID == Voxel.t.Powered || adjacentID == Voxel.t.PermanentPowered || adjacentID == Voxel.t.HardPowered || adjacentID == Voxel.t.PoweredSwitch)
                                {
                                    map.Empty(c, false, true, map);
                                    map.Fill(c, Voxel.States.Powered);
                                    this.SparksLowPriority(map.GetAbsolutePosition(c), Spark.Normal);
                                    regenerate = true;
                                }
                                else if (adjacentID == Voxel.t.Neutral && entry.Generation < maxGenerations)
                                {
                                    map.Empty(adjacent, false, true, map);
                                    this.generations[new EffectBlock.Entry {
                                                         Voxel = map, Coordinate = adjacent
                                                     }] = entry.Generation + 1;
                                    map.Fill(adjacent, Voxel.States.Blue);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Normal);
                                    regenerate = true;
                                }
                            }
                        }
                        else if (id == Voxel.t.Neutral)
                        {
                            for (int j = 0; j < 6; j++)
                            {
                                Direction   dir        = DirectionExtensions.Directions[j];
                                Voxel.Coord adjacent   = c.Move(dir);
                                Voxel.t     adjacentID = map[adjacent].ID;
                                if (adjacentID == Voxel.t.Infected || adjacentID == Voxel.t.Blue || adjacentID == Voxel.t.Powered)
                                {
                                    map.Empty(adjacent, false, true, map);
                                    map.Fill(adjacent, Voxel.States.Neutral);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Normal);
                                    regenerate = true;
                                }
                                else if (adjacentID == Voxel.t.HardInfected)
                                {
                                    map.Empty(adjacent, false, true, map);
                                    map.Fill(adjacent, Voxel.States.Hard);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Normal);
                                    regenerate = true;
                                }
                            }
                        }
                        else if (id == Voxel.t.Hard)
                        {
                            for (int j = 0; j < 6; j++)
                            {
                                Direction   dir        = DirectionExtensions.Directions[j];
                                Voxel.Coord adjacent   = c.Move(dir);
                                Voxel.t     adjacentID = map[adjacent].ID;
                                if (adjacentID == Voxel.t.HardInfected)
                                {
                                    map.Empty(adjacent, false, true, map);
                                    map.Fill(adjacent, Voxel.States.Hard);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Normal);
                                    regenerate = true;
                                }
                            }
                        }
                        else if (id == Voxel.t.Powered || id == Voxel.t.PermanentPowered || id == Voxel.t.HardPowered || id == Voxel.t.PoweredSwitch)
                        {
                            for (int j = 0; j < 6; j++)
                            {
                                Direction   dir        = DirectionExtensions.Directions[j];
                                Voxel.Coord adjacent   = c.Move(dir);
                                Voxel.t     adjacentID = map[adjacent].ID;

                                if (id == Voxel.t.Powered && adjacentID == Voxel.t.Neutral && entry.Generation < maxGenerations)
                                {
                                    map.Empty(adjacent, false, true, map);
                                    this.generations[new EffectBlock.Entry {
                                                         Voxel = map, Coordinate = adjacent
                                                     }] = entry.Generation + 1;
                                    map.Fill(adjacent, Voxel.States.Powered);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Normal);
                                    regenerate = true;
                                }
                                else if (adjacentID == Voxel.t.Blue)
                                {
                                    map.Empty(adjacent, false, true, map);
                                    map.Fill(adjacent, Voxel.States.Powered);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Normal);
                                    regenerate = true;
                                }
                                else if (adjacentID == Voxel.t.Switch)
                                {
                                    map.Empty(adjacent, true, true, map);
                                    map.Fill(adjacent, Voxel.States.PoweredSwitch);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Normal);
                                    regenerate = true;
                                }
                                else if (adjacentID == Voxel.t.Hard)
                                {
                                    map.Empty(adjacent, true, true, map);
                                    map.Fill(adjacent, Voxel.States.HardPowered);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Normal);
                                    regenerate = true;
                                }
                                else if (adjacentID == Voxel.t.Critical)
                                {
                                    map.Empty(adjacent);
                                    regenerate = true;
                                }
                            }
                        }
                        else if (id == Voxel.t.Infected || id == Voxel.t.HardInfected)
                        {
                            for (int j = 0; j < 6; j++)
                            {
                                Direction   dir        = DirectionExtensions.Directions[j];
                                Voxel.Coord adjacent   = c.Move(dir);
                                Voxel.t     adjacentID = map[adjacent].ID;
                                if (adjacentID == Voxel.t.Neutral && entry.Generation < maxGenerations)
                                {
                                    map.Empty(adjacent, false, true, map);
                                    this.generations[new EffectBlock.Entry {
                                                         Voxel = map, Coordinate = adjacent
                                                     }] = entry.Generation + 1;
                                    map.Fill(adjacent, Voxel.States.Infected);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Dangerous);
                                    regenerate = true;
                                }
                                else if (adjacentID == Voxel.t.Hard && entry.Generation < maxGenerations)
                                {
                                    map.Empty(adjacent, false, true, map);
                                    this.generations[new EffectBlock.Entry {
                                                         Voxel = map, Coordinate = adjacent
                                                     }] = entry.Generation + 1;
                                    map.Fill(adjacent, Voxel.States.HardInfected);
                                    this.SparksLowPriority(map.GetAbsolutePosition(adjacent), Spark.Dangerous);
                                    regenerate = true;
                                }
                                else if (adjacentID == Voxel.t.Critical)
                                {
                                    map.Empty(adjacent);
                                    regenerate = true;
                                }
                            }
                        }

                        if (regenerate)
                        {
                            this.toRegenerate.Add(map);
                        }
                    }
                }
            }
            for (int i = 0; i < this.toRegenerate.Count; i++)
            {
                this.toRegenerate[i].Regenerate();
            }
            this.toRegenerate.Clear();
        }
예제 #7
0
        public override void Bind(Entity entity, Main main, bool creating = false)
        {
            if (ParticleSystem.Get(main, "SnakeSparks") == null)
            {
                ParticleSystem.Add(main, "SnakeSparks",
                                   new ParticleSystem.ParticleSettings
                {
                    TextureName           = "Particles\\splash",
                    MaxParticles          = 1000,
                    Duration              = TimeSpan.FromSeconds(1.0f),
                    MinHorizontalVelocity = -7.0f,
                    MaxHorizontalVelocity = 7.0f,
                    MinVerticalVelocity   = 0.0f,
                    MaxVerticalVelocity   = 7.0f,
                    Gravity        = new Vector3(0.0f, -10.0f, 0.0f),
                    MinRotateSpeed = -2.0f,
                    MaxRotateSpeed = 2.0f,
                    MinStartSize   = 0.3f,
                    MaxStartSize   = 0.7f,
                    MinEndSize     = 0.0f,
                    MaxEndSize     = 0.0f,
                    BlendState     = Microsoft.Xna.Framework.Graphics.BlendState.AlphaBlend,
                    MinColor       = new Vector4(2.0f, 2.0f, 2.0f, 1.0f),
                    MaxColor       = new Vector4(2.0f, 2.0f, 2.0f, 1.0f),
                });
                ParticleSystem.Add(main, "SnakeSparksRed",
                                   new ParticleSystem.ParticleSettings
                {
                    TextureName           = "Particles\\splash",
                    MaxParticles          = 1000,
                    Duration              = TimeSpan.FromSeconds(1.0f),
                    MinHorizontalVelocity = -7.0f,
                    MaxHorizontalVelocity = 7.0f,
                    MinVerticalVelocity   = 0.0f,
                    MaxVerticalVelocity   = 7.0f,
                    Gravity        = new Vector3(0.0f, -10.0f, 0.0f),
                    MinRotateSpeed = -2.0f,
                    MaxRotateSpeed = 2.0f,
                    MinStartSize   = 0.3f,
                    MaxStartSize   = 0.7f,
                    MinEndSize     = 0.0f,
                    MaxEndSize     = 0.0f,
                    BlendState     = Microsoft.Xna.Framework.Graphics.BlendState.AlphaBlend,
                    MinColor       = new Vector4(1.4f, 0.8f, 0.7f, 1.0f),
                    MaxColor       = new Vector4(1.4f, 0.8f, 0.7f, 1.0f),
                });
                ParticleSystem.Add(main, "SnakeSparksYellow",
                                   new ParticleSystem.ParticleSettings
                {
                    TextureName           = "Particles\\splash",
                    MaxParticles          = 1000,
                    Duration              = TimeSpan.FromSeconds(1.0f),
                    MinHorizontalVelocity = -7.0f,
                    MaxHorizontalVelocity = 7.0f,
                    MinVerticalVelocity   = 0.0f,
                    MaxVerticalVelocity   = 7.0f,
                    Gravity        = new Vector3(0.0f, -10.0f, 0.0f),
                    MinRotateSpeed = -2.0f,
                    MaxRotateSpeed = 2.0f,
                    MinStartSize   = 0.3f,
                    MaxStartSize   = 0.7f,
                    MinEndSize     = 0.0f,
                    MaxEndSize     = 0.0f,
                    BlendState     = Microsoft.Xna.Framework.Graphics.BlendState.AlphaBlend,
                    MinColor       = new Vector4(1.4f, 1.4f, 0.7f, 1.0f),
                    MaxColor       = new Vector4(1.4f, 1.4f, 0.7f, 1.0f),
                });
            }

            Snake snake = entity.GetOrCreate <Snake>("Snake");

            entity.CannotSuspendByDistance = true;
            Transform transform = entity.GetOrCreate <Transform>("Transform");

            AI ai = entity.GetOrCreate <AI>("AI");

            Agent agent = entity.GetOrCreate <Agent>("Agent");

            const float defaultSpeed    = 5.0f;
            const float chaseSpeed      = 18.0f;
            const float closeChaseSpeed = 12.0f;
            const float crushSpeed      = 125.0f;

            VoxelChaseAI chase = entity.GetOrCreate <VoxelChaseAI>("VoxelChaseAI");

            chase.Add(new TwoWayBinding <Vector3>(transform.Position, chase.Position));
            chase.Speed.Value             = defaultSpeed;
            chase.EnablePathfinding.Value = ai.CurrentState.Value == "Chase";
            chase.Filter = delegate(Voxel.State state)
            {
                if (state == Voxel.States.Infected || state == Voxel.States.Neutral || state == Voxel.States.Hard || state == Voxel.States.HardInfected)
                {
                    return(true);
                }
                return(false);
            };
            entity.Add(new CommandBinding(chase.Delete, entity.Delete));

            PointLight positionLight = null;

            if (!main.EditorEnabled)
            {
                positionLight                   = new PointLight();
                positionLight.Serialize         = false;
                positionLight.Color.Value       = new Vector3(1.5f, 0.5f, 0.5f);
                positionLight.Attenuation.Value = 20.0f;
                positionLight.Add(new Binding <bool, string>(positionLight.Enabled, x => x != "Suspended", ai.CurrentState));
                positionLight.Add(new Binding <Vector3, string>(positionLight.Color, delegate(string state)
                {
                    switch (state)
                    {
                    case "Chase":
                    case "Crush":
                        return(new Vector3(1.5f, 0.5f, 0.5f));

                    case "Alert":
                        return(new Vector3(1.5f, 1.5f, 0.5f));

                    default:
                        return(new Vector3(1.0f, 1.0f, 1.0f));
                    }
                }, ai.CurrentState));
                entity.Add("PositionLight", positionLight);
                ParticleEmitter emitter = entity.GetOrCreate <ParticleEmitter>("Particles");
                emitter.Serialize = false;
                emitter.ParticlesPerSecond.Value = 100;
                emitter.Add(new Binding <string>(emitter.ParticleType, delegate(string state)
                {
                    switch (state)
                    {
                    case "Chase":
                    case "Crush":
                        return("SnakeSparksRed");

                    case "Alert":
                        return("SnakeSparksYellow");

                    default:
                        return("SnakeSparks");
                    }
                }, ai.CurrentState));
                emitter.Add(new Binding <Vector3>(emitter.Position, transform.Position));
                emitter.Add(new Binding <bool, string>(emitter.Enabled, x => x != "Suspended", ai.CurrentState));

                positionLight.Add(new Binding <Vector3>(positionLight.Position, transform.Position));
                emitter.Add(new Binding <Vector3>(emitter.Position, transform.Position));
                agent.Add(new Binding <Vector3>(agent.Position, transform.Position));
                Sound.AttachTracker(entity);
            }

            AI.Task checkMap = new AI.Task
            {
                Action = delegate()
                {
                    if (chase.Voxel.Value.Target == null || !chase.Voxel.Value.Target.Active)
                    {
                        entity.Delete.Execute();
                    }
                },
            };

            AI.Task checkOperationalRadius = new AI.Task
            {
                Interval = 2.0f,
                Action   = delegate()
                {
                    bool shouldBeActive = (transform.Position.Value - main.Camera.Position).Length() < snake.OperationalRadius;
                    if (shouldBeActive && ai.CurrentState == "Suspended")
                    {
                        ai.CurrentState.Value = "Idle";
                    }
                    else if (!shouldBeActive && ai.CurrentState != "Suspended")
                    {
                        ai.CurrentState.Value = "Suspended";
                    }
                },
            };

            AI.Task checkTargetAgent = new AI.Task
            {
                Action = delegate()
                {
                    Entity target = ai.TargetAgent.Value.Target;
                    if (target == null || !target.Active)
                    {
                        ai.TargetAgent.Value  = null;
                        ai.CurrentState.Value = "Idle";
                    }
                },
            };

            Func <Voxel, Direction> randomValidDirection = delegate(Voxel m)
            {
                Voxel.Coord c    = chase.Coord;
                Direction[] dirs = new Direction[6];
                Array.Copy(DirectionExtensions.Directions, dirs, 6);

                // Shuffle directions
                int i = 5;
                while (i > 0)
                {
                    int       k    = this.random.Next(i);
                    Direction temp = dirs[i];
                    dirs[i] = dirs[k];
                    dirs[k] = temp;
                    i--;
                }

                foreach (Direction dir in dirs)
                {
                    if (chase.Filter(m[c.Move(dir)]))
                    {
                        return(dir);
                    }
                }
                return(Direction.None);
            };

            Direction currentDir = Direction.None;

            chase.Add(new CommandBinding <Voxel, Voxel.Coord>(chase.Moved, delegate(Voxel m, Voxel.Coord c)
            {
                if (chase.Active)
                {
                    string currentState = ai.CurrentState.Value;
                    Voxel.t id          = m[c].ID;
                    if (id == Voxel.t.Hard)
                    {
                        m.Empty(c);
                        m.Fill(c, Voxel.States.HardInfected);
                        m.Regenerate();
                    }
                    else if (id == Voxel.t.Neutral)
                    {
                        m.Empty(c);
                        m.Fill(c, Voxel.States.Infected);
                        m.Regenerate();
                    }
                    else if (id == Voxel.t.Empty)
                    {
                        m.Fill(c, Voxel.States.Infected);
                        m.Regenerate();
                    }

                    if (currentState == "Idle")
                    {
                        if (currentDir == Direction.None || !chase.Filter(m[chase.Coord.Value.Move(currentDir)]) || this.random.Next(8) == 0)
                        {
                            currentDir = randomValidDirection(m);
                        }
                        chase.Coord.Value = chase.Coord.Value.Move(currentDir);
                    }
                    else if (snake.Path.Length > 0)
                    {
                        chase.Coord.Value = snake.Path[0];
                        snake.Path.RemoveAt(0);
                    }
                }
            }));

            Sound.AttachTracker(entity);
            SoundKiller.Add(entity, AK.EVENTS.STOP_SNAKE);
            ai.Add(new ChangeBinding <string>(ai.CurrentState, delegate(string old, string value)
            {
                if (value == "Suspended" || value == "Alert")
                {
                    AkSoundEngine.PostEvent(AK.EVENTS.STOP_SNAKE, entity);
                }
                else if (old != "Idle" && old != "Chase" && old != "Crush")
                {
                    AkSoundEngine.PostEvent(AK.EVENTS.PLAY_SNAKE, entity);
                }
            }));

            const float sightDistance   = 50.0f;
            const float hearingDistance = 0.0f;

            ai.Setup
            (
                new AI.AIState
            {
                Name  = "Suspended",
                Tasks = new[] { checkOperationalRadius },
            },
                new AI.AIState
            {
                Name  = "Idle",
                Enter = delegate(AI.AIState previous)
                {
                    Entity voxelEntity = chase.Voxel.Value.Target;
                    if (voxelEntity != null)
                    {
                        Voxel m = voxelEntity.Get <Voxel>();
                        if (currentDir == Direction.None || !chase.Filter(m[chase.Coord.Value.Move(currentDir)]))
                        {
                            currentDir = randomValidDirection(m);
                        }
                        chase.Coord.Value = chase.Coord.Value.Move(currentDir);
                    }
                },
                Tasks = new[]
                {
                    checkMap,
                    checkOperationalRadius,
                    new AI.Task
                    {
                        Interval = 1.0f,
                        Action   = delegate()
                        {
                            Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player");
                            if (a != null)
                            {
                                ai.CurrentState.Value = "Alert";
                            }
                        },
                    },
                },
            },
                new AI.AIState
            {
                Name  = "Alert",
                Enter = delegate(AI.AIState previous)
                {
                    chase.EnableMovement.Value = false;
                },
                Exit = delegate(AI.AIState next)
                {
                    chase.EnableMovement.Value = true;
                },
                Tasks = new[]
                {
                    checkMap,
                    checkOperationalRadius,
                    new AI.Task
                    {
                        Interval = 0.4f,
                        Action   = delegate()
                        {
                            if (ai.TimeInCurrentState > 3.0f)
                            {
                                ai.CurrentState.Value = "Idle";
                            }
                            else
                            {
                                Agent a = Agent.Query(transform.Position, sightDistance, hearingDistance, x => x.Entity.Type == "Player");
                                if (a != null)
                                {
                                    ai.TargetAgent.Value  = a.Entity;
                                    ai.CurrentState.Value = "Chase";
                                }
                            }
                        },
                    },
                },
            },
                new AI.AIState
            {
                Name  = "Chase",
                Enter = delegate(AI.AIState previousState)
                {
                    chase.EnablePathfinding.Value = true;
                    chase.Speed.Value             = chaseSpeed;
                },
                Exit = delegate(AI.AIState nextState)
                {
                    chase.EnablePathfinding.Value = false;
                    chase.Speed.Value             = defaultSpeed;
                },
                Tasks = new[]
                {
                    checkMap,
                    checkOperationalRadius,
                    checkTargetAgent,
                    new AI.Task
                    {
                        Interval = 0.07f,
                        Action   = delegate()
                        {
                            Vector3 targetPosition = ai.TargetAgent.Value.Target.Get <Agent>().Position;

                            float targetDistance = (targetPosition - transform.Position).Length();

                            chase.Speed.Value = targetDistance < 15.0f ? closeChaseSpeed : chaseSpeed;

                            if (targetDistance > 50.0f || ai.TimeInCurrentState > 30.0f)                                     // He got away
                            {
                                ai.CurrentState.Value = "Alert";
                            }
                            else if (targetDistance < 4.0f)                                     // We got 'im
                            {
                                // First, make sure we're not near a reset block
                                Voxel v = chase.Voxel.Value.Target.Get <Voxel>();
                                if (VoxelAStar.BroadphaseSearch(v, chase.Coord, 6, x => x.Type == Lemma.Components.Voxel.States.Reset) == null)
                                {
                                    ai.CurrentState.Value = "Crush";
                                }
                            }
                            else
                            {
                                chase.Target.Value = targetPosition;
                            }
                        },
                    },
                },
            },
                new AI.AIState
            {
                Name  = "Crush",
                Enter = delegate(AI.AIState lastState)
                {
                    // Set up cage
                    Voxel.Coord center = chase.Voxel.Value.Target.Get <Voxel>().GetCoordinate(ai.TargetAgent.Value.Target.Get <Agent>().Position);

                    int radius = 1;

                    // Bottom
                    for (int x = center.X - radius; x <= center.X + radius; x++)
                    {
                        for (int z = center.Z - radius; z <= center.Z + radius; z++)
                        {
                            snake.Path.Add(new Voxel.Coord {
                                X = x, Y = center.Y - 4, Z = z
                            });
                        }
                    }

                    // Outer shell
                    radius = 2;
                    for (int y = center.Y - 3; y <= center.Y + 3; y++)
                    {
                        // Left
                        for (int z = center.Z - radius; z <= center.Z + radius; z++)
                        {
                            snake.Path.Add(new Voxel.Coord {
                                X = center.X - radius, Y = y, Z = z
                            });
                        }

                        // Right
                        for (int z = center.Z - radius; z <= center.Z + radius; z++)
                        {
                            snake.Path.Add(new Voxel.Coord {
                                X = center.X + radius, Y = y, Z = z
                            });
                        }

                        // Backward
                        for (int x = center.X - radius; x <= center.X + radius; x++)
                        {
                            snake.Path.Add(new Voxel.Coord {
                                X = x, Y = y, Z = center.Z - radius
                            });
                        }

                        // Forward
                        for (int x = center.X - radius; x <= center.X + radius; x++)
                        {
                            snake.Path.Add(new Voxel.Coord {
                                X = x, Y = y, Z = center.Z + radius
                            });
                        }
                    }

                    // Top
                    for (int x = center.X - radius; x <= center.X + radius; x++)
                    {
                        for (int z = center.Z - radius; z <= center.Z + radius; z++)
                        {
                            snake.Path.Add(new Voxel.Coord {
                                X = x, Y = center.Y + 3, Z = z
                            });
                        }
                    }

                    chase.EnablePathfinding.Value = false;
                    chase.Speed.Value             = crushSpeed;

                    snake.CrushCoordinate.Value = chase.Coord;
                },
                Exit = delegate(AI.AIState nextState)
                {
                    chase.Speed.Value = defaultSpeed;
                    chase.Coord.Value = chase.LastCoord.Value = snake.CrushCoordinate;
                    snake.Path.Clear();
                },
                Tasks = new[]
                {
                    checkMap,
                    checkOperationalRadius,
                    checkTargetAgent,
                    new AI.Task
                    {
                        Interval = 0.01f,
                        Action   = delegate()
                        {
                            Agent a = ai.TargetAgent.Value.Target.Get <Agent>();
                            a.Damage.Execute(0.01f / 1.5f);                                     // seconds to kill
                            if (!a.Active)
                            {
                                ai.CurrentState.Value = "Alert";
                            }
                            else
                            {
                                if ((a.Position - transform.Position.Value).Length() > 5.0f)                                         // They're getting away
                                {
                                    ai.CurrentState.Value = "Chase";
                                }
                            }
                        }
                    }
                },
            }
            );

            this.SetMain(entity, main);

            entity.Add("OperationalRadius", snake.OperationalRadius);
        }
예제 #8
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 (EffectBlock.random.Next(0, 4) == 0)
                                {
                                    AkSoundEngine.PostEvent(AK.EVENTS.PLAY_BLOCK_BUILD, this.Entity);
                                }
                                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;
            }
        }
예제 #9
0
 public static bool DefaultVoxelFilter(Voxel.t x)
 {
     return(x != Components.Voxel.t.AvoidAI);
 }
예제 #10
0
파일: Footsteps.cs 프로젝트: tammukul/Lemma
        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;
            }));
        }