private void AnimateFall() { Tween.To(TargetZ, Z, x => { Z = x; if (Z <= 8f) { Depth = 0; } }, 0.5f, Ease.QuadIn).OnEnd = () => { if (TargetZ >= -0.01f) { Scale.X = 3; Scale.Y = 0.3f; } AudioEmitterComponent.Dummy(Area, Center).Emit($"level_rock_{Rnd.Int(1, 3)}", 0.5f); if (TargetZ < 0) { Finish(); } else { Tween.To(1, Scale.X, x => Scale.X = x, 0.5f); Tween.To(1, Scale.Y, x => Scale.Y = x, 0.5f).OnEnd = () => { Finish(); }; } }; }
public override void Update(float dt) { base.Update(dt); var d = Self.DistanceTo(Self.Target); if (d > 48f) { Self.Become <RunState>(); return; } if (T >= 0.66f) { Self.Done = true; Self.Exploded = true; AudioEmitterComponent.Dummy(Self.Area, Self.Center).EmitRandomized("mob_archeolog_explosion", sz: 0.2f); ExplosionMaker.Make(Self, 48f); } var flash = T % 0.33 < 0.15f; if (flash && !lastFlash) { Self.GetComponent <AudioEmitterComponent>().Emit("mob_spelunker_beep", 1f, T); } lastFlash = flash; Self.GetComponent <MobAnimationComponent>().Flash = flash; }
private void PrepareToExplode() { tillExplode = 0.5f; var a = GetComponent <ScalableSliceComponent>(); Tween.To(1.4f, a.Scale.X, x => a.Scale.X = x, 0.4f); Tween.To(0.7f, a.Scale.Y, x => a.Scale.Y = x, 0.4f); if (!HasComponent <AudioEmitterComponent>()) { AddComponent(new AudioEmitterComponent()); } AudioEmitterComponent.Dummy(Area, Center).EmitRandomized("level_tnt"); }
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 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); }
public override bool HandleEvent(Event e) { if (e is CollisionStartedEvent ev) { if (Dying || IgnoreCollisions) { return(false); } if (ev.Entity is Creature c && c.IgnoresProjectiles()) { return(false); } if (EntitiesHurt.Contains(ev.Entity)) { return(false); } if (OnCollision != null && OnCollision(this, ev.Entity)) { return(false); } if (((HurtsEveryone && (ev.Entity != Owner) || T > 1f) || ( (CanHitOwner && ev.Entity == Owner && T > 0.3f) || (ev.Entity != Owner && (!(Owner is Pet pt) || pt.Owner != ev.Entity) && (!(Owner is Orbital or) || or.Owner != ev.Entity) && !(Owner is RoomControllable && ev.Entity is Mob) && ( !(Owner is Creature ac) || !(ev.Entity is Creature bc) || (ac.IsFriendly() != bc.IsFriendly() || (bc.TryGetComponent <BuffsComponent>(out var bf) && bf.Has <CharmedBuff>())) || bc is ShopKeeper || ac is Player ) ) )) && ev.Entity.TryGetComponent <HealthComponent>(out var health) && (HurtsEveryone || CanHitOwner || !(ev.Entity is Player) || !(Owner is Player)) && !(Owner is Pet ppt && ppt.Owner == ev.Entity)) { var h = health.ModifyHealth(-Damage, Owner); if (StarterOwner is Mob && StarterOwner == ev.Entity && Owner is Player && health.Dead && T >= 0.2f) { Achievements.Unlock("bk:return_to_sender"); } EntitiesHurt.Add(ev.Entity); if (h) { OnHurt?.Invoke(this, ev.Entity); } } var mute = false; if (Run.Level.Biome is IceBiome && !(Owner is creature.bk.BurningKnight) && ev.Entity is ProjectileLevelBody lvl) { if (lvl.Break(CenterX, CenterY)) { mute = true; AudioEmitterComponent.Dummy(Area, Center).EmitRandomizedPrefixed("level_snow_break", 3); } } if (BreaksFrom(ev.Entity, ev.Body)) { if (BounceLeft > 0) { BounceLeft -= 1; } else { if (!mute && IsWall(ev.Entity, ev.Body)) { if (Owner is Player) { AudioEmitterComponent.Dummy(Area, Center).EmitRandomizedPrefixed("projectile_wall", 2, 0.5f); } else { AudioEmitterComponent.Dummy(Area, Center).EmitRandomized("projectile_wall_enemy", 0.5f); } } AnimateDeath(ev.Entity); } } } return(base.HandleEvent(e)); }
static ProjectileRegistry() { Add("skull", skull => { skull.NearDeath += p => { var c = new AudioEmitterComponent { DestroySounds = false }; p.AddComponent(c); c.Emit("mob_oldking_explode"); }; skull.OnDeath += (p, e, t) => { for (var i = 0; i < 8; i++) { var bullet = Projectile.Make(p.Owner, "small", ((float)i) / 4 * (float)Math.PI, (i % 2 == 0 ? 2 : 1) * 4 + 3); bullet.CanBeReflected = false; bullet.Center = p.Center; } }; skull.Controller += TargetProjectileController.Make(null, 0.5f); skull.Range = 5f; skull.IndicateDeath = true; skull.CanBeReflected = false; skull.GetComponent <ProjectileGraphicsComponent>().IgnoreRotation = true; }); Add("disk", p => { CollisionFilterComponent.Add(p, (entity, with) => with is Mob || with is HalfProjectileLevel ? CollisionResult.Disable : CollisionResult.Default); p.BounceLeft += 10; p.CanHitOwner = true; p.GetComponent <CircleBodyComponent>().Body.AngularVelocity = 10f; }); Add("what", p => { p.Controller += WhatController.Make(); p.GetComponent <CircleBodyComponent>().Body.AngularVelocity = 10f; }); Add("soap", p => { p.Controller += SlowdownProjectileController.Make(2); }); Add("grenade", p => { CollisionFilterComponent.Add(p, (entity, with) => { if (with is Mob) { p.BounceLeft = 0; return(CollisionResult.Enable); } return(CollisionResult.Default); }); p.Controller += SlowdownProjectileController.Make(1); p.BreaksFromWalls = false; p.OnDeath += (pr, e, t) => { ExplosionMaker.Make(pr, 16, damage: 8); }; p.Controller += (pr, dt) => { if (pr.T >= 3f) { pr.Break(); } }; }); Add("missile", p => { CollisionFilterComponent.Add(p, (entity, with) => { if (with is Mob) { p.BounceLeft = 0; return(CollisionResult.Enable); } if (with is Prop) { return(CollisionResult.Disable); } return(CollisionResult.Default); }); p.Controller += TargetProjectileController.Make(null, 0.5f); p.Controller += SmokeProjectileController.Make(); p.OnDeath += (pr, e, t) => { ExplosionMaker.Make(pr, 32); }; }); Add("shotgun", p => { p.Controller += SlowdownProjectileController.Make(1); p.BounceLeft += 1; }); Add("follower", p => { CollisionFilterComponent.Add(p, (entity, with) => { if (with is Mob) { p.BounceLeft = 0; return(CollisionResult.Enable); } if (with is Prop) { return(CollisionResult.Disable); } return(CollisionResult.Default); }); p.Controller += TargetProjectileController.MakeCursor(); p.Controller += SmokeProjectileController.Make(); p.OnDeath += (pr, e, t) => { ExplosionMaker.Make(pr, 32); }; }); Add("flak", p => { CollisionFilterComponent.Add(p, (entity, with) => { if (with is Mob) { p.BounceLeft = 0; return(CollisionResult.Enable); } return(CollisionResult.Default); }); p.Controller += SlowdownProjectileController.Make(0.5f); p.OnDeath += (pr, e, t) => { for (var i = 0; i < 8; i++) { var pr2 = Projectile.Make(pr.Owner, "shot", (float)i / 8 * (float)Math.PI * 2, 8, true, 0, null, 0.8f); pr2.Center = pr.Center; pr2.Controller += SlowdownProjectileController.Make(1); } }; p.Controller += (pr, dt) => { if (pr.T >= 1f) { pr.Break(); } }; }); Add("crash", p => { p.Controller += HsvProjectileController.Make(); p.OnDeath += (pr, ee, t) => { if (pr.T < 0.1f) { return; } for (var i = 0; i < 8; i++) { var p2 = Projectile.Make(pr.Owner, "square", (float)i / 8 * (float)Math.PI * 2, 8, true, 0, null, 0.8f); p2.Center = pr.Center; p2.Controller += HsvProjectileController.Make(1, pr.T); p2.OnDeath += (pr2, eee, t2) => { if (pr2.T < 0.1f) { return; } for (var j = 0; j < 8; j++) { var p3 = Projectile.Make(pr.Owner, "square", (float)j / 8 * (float)Math.PI * 2, 12, true, 0, null, 0.6f); p3.Center = pr2.Center; p3.Controller += HsvProjectileController.Make(1, p2.T); p3.OnDeath += (pr4, eeee, t4) => { if (pr4.T < 0.1f) { return; } for (var k = 0; k < 8; k++) { var p5 = Projectile.Make(pr.Owner, "square", (float)k / 8 * (float)Math.PI * 2, 24, true, 0, null, 0.3f); p5.Center = pr4.Center; p5.Controller += HsvProjectileController.Make(1, pr4.T); } }; } }; } }; }); Add("duck", p => { CollisionFilterComponent.Add(p, (entity, with) => with is Mob || with is Prop ? CollisionResult.Disable : CollisionResult.Default); }); Add("portal", p => { p.Center = p.Owner.GetComponent <CursorComponent>().Cursor.GamePosition; p.GetAnyComponent <BodyComponent>().Velocity *= -1; }); Add("axe", p => { CollisionFilterComponent.Add(p, (entity, with) => ((with is Creature && with != p.Owner) || ((Projectile)entity).BounceLeft == 0) ? CollisionResult.Disable : CollisionResult.Default); var ts = Timer.Add(() => { p.Item.Renderer.Hidden = false; foreach (var u in p.Item.Uses) { if (u is SimpleShootUse ss) { ss.ProjectileDied = true; break; } } }, 3f); p.Range = 5; p.PreventSpectralBreak = true; p.OnCollision = (projectile, e) => { if (Run.Level.Biome is IceBiome && e is ProjectileLevelBody lvl) { if (lvl.Break(projectile.CenterX, projectile.CenterY)) { AudioEmitterComponent.Dummy(projectile.Area, projectile.Center).EmitRandomizedPrefixed("level_snow_break", 3); } } if (projectile.BounceLeft == 0) { if (e == projectile.Owner) { projectile.Item.Renderer.Hidden = false; projectile.Break(); foreach (var u in projectile.Item.Uses) { if (u is SimpleShootUse ss) { ss.ProjectileDied = true; break; } } } else if (!(e is Mob)) { return(true); } } else if (projectile.BreaksFrom(e, null)) { if (e is Painting || e is BreakableProp || e is ExplodingBarrel || e.HasComponent <HealthComponent>()) { projectile.BounceLeft++; } else { var b = projectile.GetComponent <RectBodyComponent>().Body; b.LinearVelocity *= -1; projectile.BounceLeft = 0; projectile.EntitiesHurt.Clear(); projectile.Controller += ReturnProjectileController.Make(projectile.Owner); var pi = projectile.OnDeath; projectile.OnDeath = (pr, ee, t) => { pr.Item.Renderer.Hidden = false; foreach (var u in pr.Item.Uses) { if (u is SimpleShootUse ss) { ss.ProjectileDied = true; break; } } ts.Cancel(); pr.Owner.GetComponent <AudioEmitterComponent>().EmitRandomized("item_axe_catch"); }; pi?.Invoke(projectile, e, false); return(true); } } return(false); }; p.BounceLeft = 1; p.DieOffscreen = false; p.Rotates = true; p.Item.Renderer.Hidden = true; });
public override bool HandleEvent(Event e) { if (e is CollisionStartedEvent ev) { if (ev.Entity is HalfProjectileLevel bdd) { if (Mines) { Physics.Fixture.GetAABB(out var hitbox, 0); ProjectileLevelBody.Mine(Run.Level, hitbox.Center.X, hitbox.Center.Y); } } else if (ev.Entity is ProjectileLevelBody bd) { if (Mines) { Physics.Fixture.GetAABB(out var hitbox, 0); ProjectileLevelBody.Mine(Run.Level, hitbox.Center.X, hitbox.Center.Y); } if (Run.Level.Biome is IceBiome) { Physics.Fixture.GetAABB(out var hitbox, 0); if (bd.Break(hitbox.Center.X, hitbox.Center.Y)) { AudioEmitterComponent.Dummy(Area, Center).EmitRandomizedPrefixed("level_snow_break", 3); } } } else if (ev.Entity is Bomb) { ev.Entity.GetComponent <RectBodyComponent>().KnockbackFrom(Owner, 1f + Knockback); } else if (ev.Entity is Projectile p) { if ((p.Owner is Mob) != (Owner is Mob) && ((p.StarterOwner is Mob) != (Owner is Mob))) { if (p.CanBeReflected) { p.Owner = Owner; p.Damage *= 2f; p.Pattern?.Remove(p); var b = p.BodyComponent; var d = Math.Max(400, b.Velocity.Length() * 1.8f); var a = Owner.AngleTo(p); b.Velocity = new Vector2((float)Math.Cos(a) * d, (float)Math.Sin(a) * d); if (p.TryGetComponent <LightComponent>(out var l)) { l.Light.Color = ReflectedColor; } p.Color = ProjectileColor.Yellow; Camera.Instance.ShakeMax(4f); Owner.GetComponent <AudioEmitterComponent>().EmitRandomizedPrefixed("projectile_reflected", 2); } else if (p.CanBeBroken) { p.Break(); } } } else if (ev.Entity != Owner && (!(ev.Entity is Player) || !(Owner is Player))) { if (ev.Entity.TryGetComponent <HealthComponent>(out var health)) { if (!hurt.Contains(ev.Entity)) { if (Knockback > 0) { ev.Entity.GetAnyComponent <BodyComponent>()?.KnockbackFrom(Owner, Knockback); } if (health.ModifyHealth(-Damage, Owner)) { Owner.GetComponent <AudioEmitterComponent>().EmitRandomizedPrefixed(Sound, 3); OnHurt?.Invoke(this, ev.Entity); } hurt.Add(ev.Entity); } } else if (ev.Entity is ProjectileLevelBody && !HitWall) { HitWall = true; Owner.GetComponent <AudioEmitterComponent>().EmitRandomized("item_sword_hit_wall"); } } } return(base.HandleEvent(e)); }