public override void Init() { base.Init(); var z = Self.GetComponent <ZComponent>(); var start = z.Z; Tween.To(start + 8, start, x => z.Z = x, 0.15f, Ease.QuadIn).OnEnd = () => { Tween.To(start, z.Z, x => z.Z = x, 0.15f, Ease.QuadIn); }; Self.GetComponent <AudioEmitterComponent>().EmitRandomized("player_roll", 0.5f); var hp = Self.GetComponent <HealthComponent>(); wasUnhittable = hp.Unhittable; hp.Unhittable = true; var body = Self.GetComponent <RectBodyComponent>(); var angle = body.Acceleration.LengthSquared() > 0.1f ? body.Acceleration.ToAngle() : (Camera.Instance.ScreenToCamera(Input.Mouse.ScreenPosition) - Self.Center).ToAngle(); direction = new Vector2((float)Math.Cos(angle) * RollForce, (float)Math.Sin(angle) * RollForce); for (var i = 0; i < 4; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = Self.Center; part.Particle.Scale = Rnd.Float(0.4f, 0.8f); Self.Area.Add(part); } }
public override void Update(float dt) { base.Update(dt); if (T >= RollTime) { Become <PostRollState>(); return; } var body = Self.GetComponent <RectBodyComponent>(); body.Velocity += direction * (RollTime - T * 0.5f); body.Position += body.Velocity * dt * 0.1f; lastParticle -= dt; if (lastParticle <= 0) { lastParticle = 0.1f; var part = new ParticleEntity(Particles.Dust()); part.Position = Self.Center; part.Particle.Scale = Rnd.Float(0.4f, 0.8f); Self.Area.Add(part); } }
private bool Check(int x, int y) { var t = Level.Get(x, y); if (t == Tile.WallA || t == Tile.Transition) { Level.Set(x, y, Tile.Ice); Level.UpdateTile(x, y); Level.ReTileAndCreateBodyChunks(x, y, 2, 2); Level.Area.Add(new TileFx { X = x * 16, Y = y * 16 - 8 }); for (var i = 0; i < 3; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = new Vector2(x * 16 + 8, y * 16 + 8); Level.Area.Add(part); } Engine.Instance.Freeze = 0.5f; return(true); } return(false); }
private void SpawnWave(Entity entity) { var filter = CheckDistance(entity); MobRegistry.SetupForBiome(Run.Level.Biome.Id); var c = Rnd.Int(5, 11); for (var i = 0; i < c; i++) { Timer.Add(() => { var mob = MobRegistry.Generate(); entity.Area.Add(mob); var v = MobRegistry.FindFor(mob.GetType()); if (v?.NearWall ?? false) { mob.Center = Room.GetRandomFreeTileNearWall(filter) * 16; } else if (v?.AwayFromWall ?? false) { mob.Center = Room.GetRandomWallFreeTile(filter) * 16; } else { mob.Center = Room.GetRandomFreeTile(filter) * 16; } if (mob.TryGetComponent <ZAnimationComponent>(out var z)) { z.Animate(); } else if (mob.TryGetComponent <MobAnimationComponent>(out var m)) { m.Animate(); } var where = mob.Center; for (var j = 0; j < 8; j++) { var part = new ParticleEntity(Particles.Dust()); part.Position = where + Rnd.Vector(-8, 8); part.Particle.Scale = Rnd.Float(1f, 1.3f); part.Particle.Velocity = MathUtils.CreateVector(Rnd.AnglePI(), 40); Run.Level.Area.Add(part); part.Depth = 1; } Audio.PlaySfx("scroll"); }, (i) * 0.2f); } wave++; }
public static void PoofFrom(Vector2 where, Vector2 from, int depth = 0) { for (var i = 0; i < 4; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = where; part.Particle.Scale = Rnd.Float(0.4f, 0.8f); Run.Level.Area.Add(part); part.Depth = depth; part.Particle.Velocity = MathUtils.CreateVector((where - from).ToAngle(), 80); } }
public override void Use(Entity entity, Item item) { base.Use(entity, item); var where = entity.Center; for (var i = 0; i < 20; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = where + Rnd.Vector(-16, 16); part.Particle.Scale = Rnd.Float(1, 2f); Run.Level.Area.Add(part); } }
public override void Update(float dt) { base.Update(dt); lastParticle -= dt; if (lastParticle <= 0) { lastParticle = 0.25f; var part = new ParticleEntity(Particles.Dust()); part.Position = Self.Center; part.Particle.Scale = Rnd.Float(0.4f, 0.8f); Self.Area.Add(part); } if (!Self.HasFlight) { var anim = Self.GetComponent <PlayerGraphicsComponent>().Animation; if (anim.Frame != lastFrame) { lastFrame = anim.Frame; if (Run.Level != null && (lastFrame == 2 || lastFrame == 6)) { var x = (int)(Self.CenterX / 16); var y = (int)(Self.Bottom / 16); if (!Run.Level.IsInside(x, y)) { return; } var i = Run.Level.ToIndex(x, y); var tile = Run.Level.Get(i); var liquid = Run.Level.Liquid[i]; var room = Self.GetComponent <RoomComponent>().Room; Audio.PlaySfx(Run.Level.Biome.GetStepSound(liquid == 0 ? tile : (Tile)liquid), room != null && room.Tagged[Tags.MustBeKilled].Count > 0 ? 0.18f : 0.25f); } } } }
public static void Poof(Vector2 where, int depth = 0) { if (Settings.LowQuality) { return; } for (var i = 0; i < 4; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = where; part.Particle.Scale = Rnd.Float(0.4f, 0.8f); Run.Level.Area.Add(part); part.Depth = depth; } }
public override void Update(float dt) { base.Update(dt); if (from != null && TryGetComponent <HealthComponent>(out var h) && h.InvincibilityTimer <= 0.45f) { Done = true; if (from is Player) { var count = GlobalSave.GetInt("paintings_destroyed", 0) + 1; if (count >= 100) { Achievements.Unlock("bk:van_no_gogh"); } GlobalSave.Put("paintings_destroyed", count); } for (var i = 0; i < 4; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = Center; part.Particle.Scale = Lens.util.math.Rnd.Float(0.4f, 0.8f); Area.Add(part); part.Depth = Depth; } if (!HasComponent <AudioEmitterComponent>()) { AddComponent(new AudioEmitterComponent()); } AudioEmitterComponent.Dummy(Area, Center).EmitRandomizedPrefixed("level_chair_break", 2, 0.5f); Particles.BreakSprite(Area, GetComponent <InteractableSliceComponent>().Sprite, Position, Depth); Camera.Instance.Shake(2f); Engine.Instance.Freeze = 1f; } }
public override void Update(float dt) { base.Update(dt); if (from != null && TryGetComponent <HealthComponent>(out var h) && h.InvincibilityTimer <= 0.45f) { Done = true; if (!Camera.Instance.Overlaps(this)) { return; } if (TryGetComponent <PoolDropsComponent>(out var pool)) { pool.SpawnDrops(); } for (var i = 0; i < 4; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = Center; part.Particle.Scale = Lens.util.math.Rnd.Float(0.4f, 0.8f); Area.Add(part); } var d = AudioEmitterComponent.Dummy(Area, Center); if (Sprite == "cup" || Sprite.StartsWith("pot")) { d.EmitRandomizedPrefixed("level_cup", 2, 0.75f); } else { d.EmitRandomizedPrefixed("level_chair_break", 2, 0.75f); } Particles.BreakSprite(Area, GetComponent <SliceComponent>().Sprite, Position); Camera.Instance.Shake(2f); Engine.Instance.Freeze = 1f; } }
public override void Use(Entity entity, Item item) { if (!entity.TryGetComponent <RoomComponent>(out var r) || r.Room == null) { return; } var filter = CheckDistance(entity); MobRegistry.SetupForBiome(Run.Level.Biome.Id); for (var i = 0; i < Count; i++) { Timer.Add(() => { var mob = MobRegistry.Generate(); entity.Area.Add(mob); if (MobRegistry.FindFor(mob.GetType())?.NearWall ?? false) { mob.Center = r.Room.GetRandomFreeTileNearWall(filter) * 16; } else { mob.Center = r.Room.GetRandomFreeTile(filter) * 16; } var where = mob.Center; for (var j = 0; j < 8; j++) { var part = new ParticleEntity(Particles.Dust()); part.Position = where + Rnd.Vector(-8, 8); part.Particle.Scale = Rnd.Float(1f, 1.3f); part.Particle.Velocity = MathUtils.CreateVector(Rnd.AnglePI(), 40); Run.Level.Area.Add(part); part.Depth = 1; } Audio.PlaySfx("scroll"); }, (i - 1) * 0.2f); } }
public static ProjectileUpdateCallback Make() { var t = 0f; return((p, dt) => { t += dt; if (t >= 0.1f) { t = 0; var part = new ParticleEntity(Particles.Dust()); p.Area.Add(part); part.Particle.Position = p.Center; part.Particle.Velocity = p.BodyComponent.Velocity * -0.2f; part.Particle.Scale = Rnd.Float(0.6f, 0.8f); part.Depth = Layers.Creature; } }); }
public static void BreakRock(Level level, Dot ww, int x, int y, Tile l) { AudioEmitterComponent.Dummy(level.Area, ww).Emit($"level_rock_{Rnd.Int(1, 3)}", 0.5f); if (l.IsRock()) { Drop.Create(l == Tile.TintedRock ? "bk:tinted_rock" : "bk:rock", null, level.Area, ww); } for (var i = 0; i < 3; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = ww; level.Area.Add(part); } Particles.BreakSprite(level.Area, (l == Tile.TintedRock ? level.Tileset.TintedRock : (l == Tile.MetalBlock ? level.Tileset.MetalBlock : level.Tileset.Rock))[Rnd.Int(4)], ww); level.Set(x, y, Tile.Ember); level.UpdateTile(x, y); level.ReCreateBodyChunk(x, y); }
private void CheckSupport() { if (!HadNoSupport && HasNoSupport && !Engine.EditingLevel) { if (Send(new LostSupportEvent { Who = Entity })) { return; } Entity.Position = LastSupportedPosition; for (var i = 0; i < 4; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = Entity.Center; part.Particle.Scale = Rnd.Float(0.4f, 0.8f); Entity.Area.Add(part); } } }
protected virtual void AnimateDeath(Entity from, bool timeout = false) { if (Dying) { return; } Dying = true; deathTimer = 0.1f; try { var l = Math.Min(15, BodyComponent.Velocity.Length()); if (l > 1f) { var a = VectorExtension.ToAngle(BodyComponent.Velocity); for (var i = 0; i < 4; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = Center; Run.Level.Area.Add(part); part.Particle.Velocity = MathUtils.CreateVector(a + Rnd.Float(-0.4f, 0.4f), l); part.Depth = Layers.WindFx; part.Particle.Scale = 0.7f; } } Camera.Instance.ShakeMax(4); OnDeath?.Invoke(this, from, timeout); BodyComponent.Velocity = Vector2.Zero; } catch (Exception e) { Log.Error(e); } }
public static void Make(Entity whoHurts, float hurtRadius = 32f, bool leave = true, Vec2 where = null, float damage = 16, float scale = 1, bool damageOwner = true) { Camera.Instance.Shake(10 * scale); Audio.SfxVolumeBuffer = 0.5f; Audio.SfxVolumeBufferResetTimer = 1f; var w = where == null ? whoHurts.Center : new Vector2(where.X, where.Y); AnimationUtil.Explosion(w, scale); for (var i = 0; i < 4; i++) { var explosion = new ParticleEntity(Particles.Animated("explosion", "smoke")); explosion.Position = w; whoHurts.Area.Add(explosion); explosion.Depth = 31; explosion.Particle.Scale = scale; explosion.Particle.AngleVelocity = 0; explosion.AddShadow(); var a = explosion.Particle.Angle - Math.PI / 2; var d = 16; explosion.Particle.Position += new Vector2((float)Math.Cos(a) * d, (float)Math.Sin(a) * d); if (i == 0) { explosion.AddComponent(new AudioEmitterComponent { DestroySounds = false }); explosion.GetComponent <AudioEmitterComponent>().EmitRandomizedPrefixed("level_explosion", 3); } } for (var i = 0; i < 6; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = w + new Vector2(Rnd.Int(-4, 4), Rnd.Int(-4, 4)); whoHurts.Area.Add(part); part.Depth = 30; part.Particle.Velocity = MathUtils.CreateVector(Rnd.AnglePI(), 80); } Engine.Instance.Split = 1f; Engine.Instance.Flash = 1f; Engine.Instance.Freeze = 1f; var damager = whoHurts; if (whoHurts is Bomb b && b.Owner != null) { damager = b.Owner; } foreach (var e in whoHurts.Area.GetEntitesInRadius(w, hurtRadius, typeof(ExplodableComponent))) { if (e == whoHurts && !damageOwner) { continue; } e.GetAnyComponent <BodyComponent>()?.KnockbackFrom(whoHurts, 4f); e.GetComponent <ExplodableComponent>().HandleExplosion(damager, whoHurts, damage); } if (Settings.Flashes) { Camera.Instance.TextureZoom -= 0.05f; Tween.To(1f, Camera.Instance.TextureZoom, x => Camera.Instance.TextureZoom = x, 0.2f); } if (leave) { whoHurts.Area.Add(new ExplosionLeftOver { Center = w }); } var xx = (int)Math.Floor(w.X / 16f); var yy = (int)Math.Floor(w.Y / 16f); var r = (int)Math.Floor(hurtRadius / 16f); var level = Run.Level; var ice = level.Biome is IceBiome; for (int x = -r; x <= r; x++) { for (int y = -r; y <= r; y++) { var xm = x * 16; var ym = y * 16; if (Math.Sqrt(xm * xm + ym * ym) <= hurtRadius) { var index = level.ToIndex(x + xx, y + yy); var l = level.Get(index, true); var ww = new Dot((x + xx) * 16 + 8, (y + yy) * 16 + 8); if (l.IsRock()) { BreakRock(level, ww, x + xx, y + yy, l); continue; } var tile = level.Get(index); if (tile == Tile.Crack) { DiscoverCrack(whoHurts, level, x + xx, y + yy); } else if (tile == Tile.Planks || (ice && tile == Tile.WallA)) { level.Break((x + xx) * 16, (y + yy) * 16); } } } } }
public override void AddComponents() { base.AddComponents(); Width = 31; Height = 33; AddComponent(new AnimationComponent("emerald_golem")); AddComponent(new SensorBodyComponent(-Npc.Padding, -Npc.Padding, Width + Npc.Padding * 2, Height + Npc.Padding, BodyType.Static)); AddComponent(new RectBodyComponent(2, 17, 27, 16, BodyType.Static)); AddComponent(new InteractableComponent(Interact) { CanInteract = e => !broken }); GetComponent <DialogComponent>().Dialog.Voice = 15; Dialogs.RegisterCallback("eg_0", (d, c) => { if (broken) { return(null); } if (((ChoiceDialog)d).Choice == 0) { Timer.Add(() => { GetComponent <DialogComponent>().StartAndClose(Locale.Get("eg_1"), 3); }, 0.2f); var inv = c.To.GetComponent <InventoryComponent>(); var a = c.To.Area; for (var i = 0; i < Amount; i++) { inv.Pickup(Items.CreateAndAdd("bk:emerald", a)); } Timer.Add(() => { inv.Pickup(Items.CreateAndAdd(Scourge.GenerateItemId(), a)); }, 1f); Timer.Add(() => { GetComponent <AnimationComponent>().Animate(() => { Done = true; Engine.Instance.Flash = 1f; Camera.Instance.Shake(8); for (var i = 0; i < 4; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = Center + Rnd.Vector(-16, 16); part.Particle.Scale = Rnd.Float(1f, 2f); Run.Level.Area.Add(part); part.Depth = 1; } }); }, 4f); broken = true; return(null); } else if (GlobalSave.IsTrue("bk:emerald_gun")) { Timer.Add(() => { GetComponent <DialogComponent>().StartAndClose(Locale.Get("eg_1"), 3); }, 0.2f); var inv = c.To.GetComponent <InventoryComponent>(); var a = c.To.Area; inv.Pickup(Items.CreateAndAdd("bk:emerald_gun", a)); Timer.Add(() => { inv.Pickup(Items.CreateAndAdd(Scourge.GenerateItemId(), a)); }, 1f); Timer.Add(() => { GetComponent <AnimationComponent>().Animate(() => { Done = true; Engine.Instance.Flash = 1f; Camera.Instance.Shake(8); for (var i = 0; i < 4; i++) { var part = new ParticleEntity(Particles.Dust()); part.Position = Center + Rnd.Vector(-16, 16); part.Particle.Scale = Rnd.Float(1f, 2f); Run.Level.Area.Add(part); part.Depth = 1; } }); }, 4f); broken = true; return(null); } return(null); }); Subscribe <RoomChangedEvent>(); }
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); } } }