Beispiel #1
0
    IEnumerator StartTileHurricane(GameObject tile)
    {
        // 1. Emit particles
        TileParticle ps = tile.GetComponent <TileParticle>();

        ps.PlayAir();

        // 2. Add gravity and let tiles fall down
        yield return(new WaitForSeconds(1));

        MeshCollider mc = tile.GetComponent <MeshCollider>();
        Rigidbody    rb = tile.GetComponent <Rigidbody>();

        mc.convex      = true;
        rb.isKinematic = false;
        rb.useGravity  = true;
        AddTileForce(rb);

        // 3. Enable drag
        hurricaneActive = true;

        yield return(new WaitForSeconds(10));

        Destroy(tile);
    }
Beispiel #2
0
        private void SpawnReward()
        {
            if (Run.Depth < 1 || Type != RoomType.Regular || Rnd.Chance(35 - Run.Luck))
            {
                return;
            }

            foreach (var e in Tagged[Tags.LevelSave])
            {
                if (e is MovingPlatform)
                {
                    // To avoid it getting stuck
                    return;
                }
            }

            var where = new Dot(MapX + MapW / 2, MapY + MapH / 2);

            for (var x = -1; x < 2; x++)
            {
                for (var y = -1; y < 2; y++)
                {
                    var x1 = x;
                    var y1 = y;

                    Timer.Add(() => {
                        var part = new TileParticle();

                        part.Top       = Run.Level.Tileset.FloorD[0];
                        part.TopTarget = Run.Level.Tileset.WallTopADecor;
                        part.Side      = Run.Level.Tileset.FloorSidesD[0];
                        part.Sides     = Run.Level.Tileset.WallSidesA[2];
                        part.Tile      = Tile.FloorD;

                        part.X        = (where.X + x1) * 16;
                        part.Y        = (where.Y + y1) * 16 + 8;
                        part.Target.X = (where.X + x1) * 16;
                        part.Target.Y = (where.Y + y1) * 16 + 8;
                        part.TargetZ  = -8f;

                        Area.Add(part);
                    }, Rnd.Float(1f));
                }
            }

            Timer.Add(() => {
                var reward          = CreateReward();
                reward.BottomCenter = where * 16 + new Vector2(8, 24);
                AnimationUtil.Poof(reward.Center);
            }, 1.5f);
        }
Beispiel #3
0
            public override void Init()
            {
                base.Init();

                var spot = PickDot();
                var to   = PickDot();

                if (spot == null || to == null)
                {
                    return;
                }

                var sx = Rnd.Int(1, 4);
                var sy = Rnd.Int(1, 4);

                for (var x = sx > 2 ? -1 : 0; x < sx; x++)
                {
                    for (var y = sy > 2 ? -1 : 0; y < sy; y++)
                    {
                        var x1 = x;
                        var y1 = y;

                        Timer.Add(() => {
                            var part = new TileParticle();

                            part.FromBottom = true;
                            part.Top        = Run.Level.Tileset.FloorA[0];
                            part.TopTarget  = Run.Level.Tileset.WallTopADecor;
                            part.Side       = Run.Level.Tileset.WallA[0];
                            part.Sides      = Run.Level.Tileset.WallSidesA[2];
                            part.Tile       = Tile.WallA;

                            part.X        = (spot.X + x1) * 16;
                            part.Y        = (spot.Y + y1) * 16 + 8;
                            part.Target.X = (to.X + x1) * 16;
                            part.Target.Y = (to.Y + y1) * 16 + 8;

                            Self.Area.Add(part);
                        }, Rnd.Float(1f));
                    }
                }
            }
Beispiel #4
0
        public override void Update(float dt)
        {
            base.Update(dt);

            if (Died)
            {
                if (!cleared)
                {
                    cleared = true;
                    GetComponent <DialogComponent>().Close();

                    foreach (var p in Area.Tagged[Tags.Projectile])
                    {
                        AnimationUtil.Poof(p.Center);
                        ((Projectile)p).Break(null);
                    }

                    try {
                        var a = GetComponent <RoomComponent>().Room.Tagged[Tags.MustBeKilled].ToArray();

                        foreach (var p in a)
                        {
                            if (!(p is Boss))
                            {
                                AnimationUtil.Poof(p.Center);
                                ((Creature)p).Kill(this);
                            }
                        }
                    } catch (Exception e) {
                        Log.Error(e);
                    }
                }

                if (deathTimer >= 3f && !Placed)
                {
                    Placed = true;
                    CreateGore(null);

                    if (this is bk.BurningKnight)
                    {
                    }
                    else
                    {
                        HandleEvent(new DefeatedEvent {
                            Boss = this
                        });
                    }

                    var player = LocalPlayer.Locate(Area);
                    var doors  = new List <DoorTile>();

                    if (player != null)
                    {
                        var stats = player.GetComponent <StatsComponent>();
                        var e     = new DealChanceCalculateEvent();

                        if (!stats.TookDamageInRoom)
                        {
                            Achievements.Unlock("bk:dodge_master");
                        }

                        e.GrannyStartChance = stats.SawDeal && !stats.TookDeal ? stats.GrannyChance : 0;
                        e.GrannyChance      = e.GrannyStartChance;
                        e.DmStartChance     = stats.DMChance;
                        e.DmChance          = e.DmStartChance;

                        player.HandleEvent(e);

                        var gr = Rnd.Chance(e.GrannyChance * 100);
                        var dm = Rnd.Chance(e.DmChance * 100);

                        if (gr || (dm && e.OpenBoth))
                        {
                            foreach (var r in Area.Tagged[Tags.Room])
                            {
                                var room = (Room)r;

                                if (room.Type == RoomType.Granny)
                                {
                                    room.OpenHiddenDoors();

                                    foreach (var d in room.Doors)
                                    {
                                        doors.Add(new DoorTile {
                                            Door = d,
                                            Tile = Tile.GrannyFloor
                                        });
                                    }

                                    break;
                                }
                            }
                        }

                        if (dm || (gr && e.OpenBoth))
                        {
                            foreach (var r in Area.Tagged[Tags.Room])
                            {
                                var room = (Room)r;

                                if (room.Type == RoomType.OldMan)
                                {
                                    room.OpenHiddenDoors();

                                    foreach (var d in room.Doors)
                                    {
                                        doors.Add(new DoorTile {
                                            Door = d,
                                            Tile = Tile.EvilFloor
                                        });
                                    }

                                    break;
                                }
                            }
                        }
                    }

                    if (doors.Count > 0)
                    {
                        var rm          = GetComponent <RoomComponent>().Room;
                        var level       = Run.Level;
                        var cx          = rm.MapX + rm.MapW / 2f;
                        var cy          = rm.MapY + rm.MapH / 2f;
                        var grannyDoors = new List <Door>();
                        var evilDoors   = new List <Door>();

                        foreach (var d in doors)
                        {
                            if (d.Tile == Tile.GrannyFloor)
                            {
                                grannyDoors.Add(d.Door);
                            }
                            else
                            {
                                evilDoors.Add(d.Door);
                            }
                        }

                        rm.PaintTunnel(grannyDoors, Tile.GrannyFloor);
                        rm.PaintTunnel(evilDoors, Tile.EvilFloor);

                        rm.ApplyToEachTile((x, y) => {
                            var t = level.Get(x, y);

                            if (t == Tile.GrannyFloor || t == Tile.EvilFloor)
                            {
                                level.Set(x, y, Tile.FloorA);

                                Timer.Add(() => {
                                    var part = new TileParticle();

                                    part.Top       = t == Tile.GrannyFloor ? Tilesets.Biome.GrannyFloor[0] : Tilesets.Biome.EvilFloor[0];
                                    part.TopTarget = Run.Level.Tileset.WallTopADecor;
                                    part.Side      = Run.Level.Tileset.FloorSidesD[0];
                                    part.Sides     = Run.Level.Tileset.WallSidesA[2];
                                    part.Tile      = t;

                                    part.X        = x * 16;
                                    part.Y        = y * 16;
                                    part.Target.X = x * 16;
                                    part.Target.Y = y * 16;
                                    part.TargetZ  = -8f;

                                    Area.Add(part);
                                }, 1f + Rnd.Float(0.2f) + MathUtils.Distance(x - cx, y - cy) / 6f);
                            }
                        }, -1);

                        level.TileUp();
                        level.CreateBody();
                    }

                    Done = true;
                    PlaceRewards();

                    if (ResetCam)
                    {
                        Timer.Add(() => { ((InGameState)Engine.Instance.State).ResetFollowing(); }, 0.5f);
                    }
                }
                else
                {
                    deathTimer    += dt;
                    lastExplosion -= dt;

                    if (lastExplosion <= 0)
                    {
                        lastExplosion = 0.3f;
                        AnimationUtil.Explosion(Center + new Vector2(Rnd.Float(-16, 16), Rnd.Float(-16, 16)));
                        Camera.Instance.Shake(10);
                        Audio.PlaySfx($"level_explosion_{Rnd.Int(1, 4)}");
                    }

                    if (deathTimer > 2.5f)
                    {
                        Engine.Instance.FlashColor = new Color(1f, 1f, 1f, (deathTimer - 2.5f) * 2f);
                        Engine.Instance.Flash      = 0.01f;
                    }
                }

                return;
            }

            if (!(GetComponent <StateComponent>().StateInstance is FriendlyState) && HasHealthbar && HealthBar == null)
            {
                HealthBar = new HealthBar(this);
                Engine.Instance.State.Ui.Add(HealthBar);
                AddPhases();

                Engine.Instance.State.Ui.Add(new UiBanner(Locale.Get(GetId())));
            }
        }
Beispiel #5
0
        public override bool HandleEvent(Event e)
        {
            if (e is LostSupportEvent)
            {
                if (GetComponent <HealthComponent>().Unhittable)
                {
                    return(true);
                }

                if (!GetComponent <BuffsComponent>().PitImmunity)
                {
                    GetComponent <HealthComponent>().ModifyHealth(-1, Run.Level);
                }


                for (var i = 0; i < 4; i++)
                {
                    var part = new ParticleEntity(Particles.Dust());

                    part.Position       = Center;
                    part.Particle.Scale = Rnd.Float(0.4f, 0.8f);
                    Area.Add(part);
                }
            }
            else if (e is RoomChangedEvent c)
            {
                if (c.New == null || Run.Level == null || Camera.Instance == null)
                {
                    return(base.HandleEvent(e));
                }

                if (c.New.Tagged[Tags.MustBeKilled].Count > 0)
                {
                    Audio.PlaySfx("level_door_shut");

                    foreach (var p in Area.Tagged[Tags.Player])
                    {
                        if (p.GetComponent <RoomComponent>().Room != c.New)
                        {
                            AnimationUtil.Poof(p.Center);
                            p.Center = Center;
                            AnimationUtil.Poof(p.Center);
                        }
                    }
                }

                ((InGameState)Engine.Instance.State).ResetFollowing();

                var pr = (PixelPerfectGameRenderer)Engine.Instance.StateRenderer;

                if (c.Old != null)
                {
                    if (Scourge.IsEnabled(Scourge.OfLost))
                    {
                        c.Old.Hide();
                    }

                    if (c.Old.Type == RoomType.DarkMarket || c.Old.Type == RoomType.Hidden)
                    {
                        pr.EnableClip = false;
                        c.Old.Hide(true);
                        InBuilding = false;
                        ((InGameState)Engine.Instance.State).UpdateRainVolume();
                    }
                }

                if (c.New.Type == RoomType.DarkMarket)
                {
                    Achievements.Unlock("bk:dark_market");
                }

                if (c.New.Type == RoomType.DarkMarket || c.New.Type == RoomType.Hidden)
                {
                    pr.EnableClip   = true;
                    pr.ClipPosition = new Vector2(c.New.X + 16, c.New.Y + 16);
                    pr.ClipSize     = new Vector2(c.New.Width - 16, c.New.Height - 32);
                    InBuilding      = true;
                    ((InGameState)Engine.Instance.State).UpdateRainVolume();
                }
                else
                {
                    pr.EnableClip = false;
                }

                if (c.New.Type == RoomType.Shop)
                {
                    Audio.PlaySfx("level_door_bell");
                }

                c.New.Discover();
                var level = Run.Level;

                if (InGameState.Ready)
                {
                    switch (c.New.Type)
                    {
                    case RoomType.Secret:
                    case RoomType.Special:
                    case RoomType.Shop:
                    case RoomType.SubShop:
                    case RoomType.Treasure: {
                        foreach (var door in c.New.Doors)
                        {
                            if (door.TryGetComponent <LockComponent>(out var component) && component.Lock is GoldLock)
                            {
                                if (!(c.New.Type == RoomType.Shop && ((door.Rooms[0] != null && door.Rooms[0].Type == RoomType.SubShop) ||
                                                                      (door.Rooms[1] != null && door.Rooms[1].Type == RoomType.SubShop))))
                                {
                                    component.Lock.SetLocked(false, this);
                                }
                            }
                        }

                        break;
                    }

                    case RoomType.OldMan:
                    case RoomType.Granny: {
                        if (c.New.Type == RoomType.OldMan)
                        {
                            GetComponent <StatsComponent>().SawDeal = true;
                        }

                        c.New.OpenHiddenDoors();

                        foreach (var r in Area.Tagged[Tags.Room])
                        {
                            var room = (Room)r;

                            if (room.Type == (c.New.Type == RoomType.OldMan ? RoomType.Granny : RoomType.OldMan))
                            {
                                room.CloseHiddenDoors();
                                break;
                            }
                        }

                        break;
                    }
                    }

                    if (c.New.Type == RoomType.Secret)
                    {
                        ExplosionMaker.CheckForCracks(level, c.New, this);
                    }
                }

                if (c.Old != null)
                {
                    if (c.Old.Type == RoomType.OldMan)
                    {
                        var found = false;

                        foreach (var p in c.Old.Tagged[Tags.Player])
                        {
                            if (p != this && p is Player)
                            {
                                found = true;

                                break;
                            }
                        }

                        if (!found)
                        {
                            c.Old.CloseHiddenDoors();
                        }
                    }
                    else if (c.Old.Type == RoomType.Treasure && Run.Type != RunType.BossRush && !Rnd.Chance(5))
                    {
                        var found = false;

                        foreach (var p in c.Old.Tagged[Tags.Player])
                        {
                            if (p != this && p is Player)
                            {
                                found = true;

                                break;
                            }
                        }

                        if (!found)
                        {
                            foreach (var door in c.Old.Doors)
                            {
                                var x = (int)Math.Floor(door.CenterX / 16);
                                var y = (int)Math.Floor(door.Bottom / 16);
                                var t = level.Get(x, y);

                                if (level.Get(x, y).Matches(TileFlags.Passable))
                                {
                                    var index = level.ToIndex(x, y);

                                    level.Set(index, level.Biome is IceBiome ? Tile.WallB : Tile.WallA);
                                    level.UpdateTile(x, y);
                                    level.ReCreateBodyChunk(x, y);
                                    level.LoadPassable();

                                    Camera.Instance.Shake(10);
                                }
                            }

                            c.Old.ApplyToEachTile((x, y) => {
                                if (Run.Level.Get(x, y).IsWall())
                                {
                                    return;
                                }

                                Timer.Add(() => {
                                    var part = new TileParticle();

                                    part.Top       = Run.Level.Tileset.WallTopADecor;
                                    part.TopTarget = Run.Level.Tileset.WallTopADecor;
                                    part.Side      = Run.Level.Tileset.FloorSidesD[0];
                                    part.Sides     = Run.Level.Tileset.WallSidesA[2];
                                    part.Tile      = Tile.WallA;

                                    part.X        = x * 16;
                                    part.Y        = y * 16;
                                    part.Target.X = x * 16;
                                    part.Target.Y = y * 16;
                                    part.TargetZ  = -8f;

                                    Area.Add(part);
                                }, Rnd.Float(0.5f));
                            });

                            foreach (var d in c.Old.Doors)
                            {
                                d.Done = true;
                            }

                            c.Old.Done = true;
                        }
                    }
                }

                // Darken the lighting in evil rooms
                if (c.New.Type == RoomType.OldMan || c.New.Type == RoomType.Spiked)
                {
                    Tween.To(0.7f, Lights.RadiusMod, x => Lights.RadiusMod = x, 0.3f);
                }
                else if (c.Old != null && (c.Old.Type == RoomType.OldMan || c.Old.Type == RoomType.Spiked))
                {
                    Tween.To(1f, Lights.RadiusMod, x => Lights.RadiusMod = x, 0.3f);
                }
            }
            else if (e is HealthModifiedEvent hm)
            {
                if (hm.Amount < 0)
                {
                    if ((hm.From is Mob m && m.HasPrefix) || (hm.From is creature.bk.BurningKnight k && k.InFight) || hm.From is BkOrbital)
                    {
                        hm.Amount = Math.Min(hm.Amount, -2);
                    }
                    else if (hm.Type != DamageType.Custom && hm.Type != DamageType.Explosive)
                    {
                        hm.Amount = Math.Max(-1, hm.Amount);
                    }
                }
            }