public override Task <Entity> CreateEntity(EntityHierarchyItemViewModel parent) { var name = ComputeNewName(parent, "AudioEmitter"); var component = new AudioEmitterComponent(); return(CreateEntityWithComponent(name, component)); }
/// <summary> /// Created a new <see cref="AudioEmitterSoundController"/> instance. /// </summary> /// <param name="parent">The parent AudioEmitterComponent to which the controller is associated.</param> /// <param name="sound">The underlying SoundBase to be controlled</param> /// <remarks>A <see cref="sound"/> can be associated to several controllers.</remarks> internal AudioEmitterSoundController(AudioEmitterComponent parent, SoundBase sound) { this.sound = sound ?? throw new ArgumentNullException(nameof(sound)); emitter = parent; Volume = 1; }
public void TestDistanceDopplerScale() { var testInst = new AudioEmitterComponent(); Assert.Throws <ArgumentOutOfRangeException>(() => testInst.DistanceScale = -0.1f, "DistanceScale did not throw ArgumentOutOfRangeException"); Assert.Throws <ArgumentOutOfRangeException>(() => testInst.DopplerScale = -0.1f, "DopplerScale did not throw ArgumentOutOfRangeException"); }
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 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 async Task Execute() { // Play explosion sound AudioEmitterComponent audioEmitter = Entity.Get <AudioEmitterComponent>(); explosionSound = audioEmitter["Explosion"]; explosionSound.PlayAndForget(); Entity.Transform.UpdateWorldMatrix(); var model = Entity.Get <ModelComponent>(); // Scatter all the Rigidbody parts of the scattered drone model var fracturedRigidBodies = Entity.GetAll <RigidbodyComponent>(); Vector3 explosionCenter = Entity.Transform.WorldMatrix.TranslationVector; Random explosionRandom = new Random(); foreach (var fragment in fracturedRigidBodies) { Vector3 dir = fragment.PhysicsWorldTransform.TranslationVector - explosionCenter; dir.Normalize(); fragment.IsKinematic = false; if (model.Skeleton.Nodes[fragment.BoneIndex].Name != "Drone_D_part_015") { fragment.ApplyTorqueImpulse(-dir * (float)(explosionRandom.NextDouble() * 0.2f)); fragment.ApplyImpulse(dir * (float)(explosionRandom.NextDouble() * 2.5f + 2.5f)); } } await Task.Delay(30000); // Despawn after a while to clean up drone parts SceneSystem.SceneInstance.RootScene.Entities.Remove(Entity); }
public override void Start() { // We need to create an instance of Sound object in order to play them ukuleleInstance = UkuleleSound.CreateInstance(); audioEmitterComponent = Entity.Get <AudioEmitterComponent>(); gunSoundEmitter = audioEmitterComponent["Gun"]; }
public void TestInitialization() { var testInst = new AudioEmitterComponent(); Assert.AreEqual(testInst.DistanceScale, 1, "Default value of the distance scale is not correct"); Assert.AreEqual(testInst.DopplerScale, 1, "Default value of the doppler scale is not correct"); Assert.IsFalse(testInst.ShouldBeProcessed, "Default value of ShouldBeProcessed si not correct"); Assert.IsTrue(testInst.SoundEffectToController.Keys.Count == 0, "Controller list is not empty"); }
/// <summary> /// Created a new <see cref="AudioEmitterSoundController"/> instance. /// </summary> /// <param name="parent">The parent AudioEmitterComponent to which the controller is associated.</param> /// <param name="sound">The underlying Sound to be controlled</param> /// <remarks>A <see cref="sound"/> can be associated to several controllers.</remarks> internal AudioEmitterSoundController(AudioEmitterComponent parent, Sound sound) { if (sound == null) { throw new ArgumentNullException(nameof(sound)); } this.sound = sound; Volume = 1; }
/// <summary> /// Created a new <see cref="AudioEmitterSoundController"/> instance. /// </summary> /// <param name="parent">The parent AudioEmitterComponent to which the controller is associated.</param> /// <param name="soundEffect">The underlying SoundEffect to be controlled</param> /// <remarks>A <see cref="SoundEffect"/> can be associated to several controllers.</remarks> internal AudioEmitterSoundController(AudioEmitterComponent parent, SoundEffect soundEffect) { if (soundEffect == null) { throw new ArgumentNullException("soundEffect"); } this.soundEffect = soundEffect; this.parent = parent; Volume = 1; }
public void TestAttachDetachSounds() { var testInst = new AudioEmitterComponent(); using (var game = new Game()) { Game.InitializeAssetDatabase(); using (var audioStream1 = ContentManager.FileProvider.OpenStream("EffectToneA", VirtualFileMode.Open, VirtualFileAccess.Read)) using (var audioStream2 = ContentManager.FileProvider.OpenStream("EffectBip", VirtualFileMode.Open, VirtualFileAccess.Read)) using (var audioStream3 = ContentManager.FileProvider.OpenStream("EffectStereo", VirtualFileMode.Open, VirtualFileAccess.Read)) { var sound1 = SoundEffect.Load(game.Audio.AudioEngine, audioStream1); var sound2 = SoundEffect.Load(game.Audio.AudioEngine, audioStream2); var sound3 = SoundEffect.Load(game.Audio.AudioEngine, audioStream3); // Attach two soundEffect and check that their controller are correctly created. AudioEmitterSoundController soundController1 = null; AudioEmitterSoundController soundController2 = null; Assert.DoesNotThrow(() => testInst.AttachSoundEffect(sound1), "Adding a first soundEffect failed"); Assert.DoesNotThrow(() => soundController1 = testInst.SoundEffectToController[sound1], "There are no sound controller for sound1."); Assert.IsNotNull(soundController1, "Sound controller for sound1 is null"); Assert.DoesNotThrow(() => testInst.AttachSoundEffect(sound2), "Adding a second soundEffect failed"); Assert.DoesNotThrow(() => soundController2 = testInst.SoundEffectToController[sound2], "There are no sound controller for sound1."); Assert.IsNotNull(soundController2, "Sound controller for sound2 is null"); // Remove the two soundEffect and check that their controller are correctly erased. Assert.DoesNotThrow(() => testInst.DetachSoundEffect(sound2), "Removing a first soundEffect failed"); Assert.IsFalse(testInst.SoundEffectToController.ContainsKey(sound2), "The controller for sound2 is still present in the list."); Assert.DoesNotThrow(() => testInst.DetachSoundEffect(sound1), "Removing a second soundEffect failed"); Assert.IsFalse(testInst.SoundEffectToController.ContainsKey(sound1), "The controller for sound1 is still present in the list."); Assert.IsTrue(testInst.SoundEffectToController.Keys.Count == 0, "There are some controller left in the component list."); // Check the exception thrwon by attachSoundEffect. Assert.Throws <ArgumentNullException>(() => testInst.AttachSoundEffect(null), "AttachSoundEffect did not throw ArgumentNullException"); Assert.Throws <InvalidOperationException>(() => testInst.AttachSoundEffect(sound3), "AttachSoundEffect did not throw InvalidOperationException."); // Check the exception thrown by detachSoundEffect. Assert.Throws <ArgumentNullException>(() => testInst.DetachSoundEffect(null), "DetachSoundEffect did not throw ArgumentNullException."); Assert.Throws <ArgumentException>(() => testInst.DetachSoundEffect(sound1), "DetachSoundEffect did not throw ArgumentException "); } } }
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 (!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 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 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 void TestGetController() { var testInst = new AudioEmitterComponent(); using (var game = new Game()) { Game.InitializeAssetDatabase(); using (var audioStream1 = ContentManager.FileProvider.OpenStream("EffectToneA", VirtualFileMode.Open, VirtualFileAccess.Read)) using (var audioStream2 = ContentManager.FileProvider.OpenStream("EffectBip", VirtualFileMode.Open, VirtualFileAccess.Read)) { var sound1 = SoundEffect.Load(game.Audio.AudioEngine, audioStream1); var sound2 = SoundEffect.Load(game.Audio.AudioEngine, audioStream2); AudioEmitterSoundController soundController1 = null; AudioEmitterSoundController soundController2 = null; // Add two soundEffect and try to get their controller. testInst.AttachSoundEffect(sound1); Assert.DoesNotThrow(() => soundController1 = testInst.GetSoundEffectController(sound1), "Failed to get the controller associated to the soundEffect1."); testInst.AttachSoundEffect(sound2); Assert.DoesNotThrow(() => soundController2 = testInst.GetSoundEffectController(sound2), "Failed to get the controller associated to the soundEffect1."); // Suppress the two SoundEffects and check that the function throws the correct exception (ArgumentException) testInst.DetachSoundEffect(sound1); Assert.Throws <ArgumentException>(() => testInst.GetSoundEffectController(sound1), "GetController did not throw ArgumentException but sound1 was supposed to be detached."); testInst.DetachSoundEffect(sound2); Assert.Throws <ArgumentException>(() => testInst.GetSoundEffectController(sound2), "GetController did not throw ArgumentException but sound2 was supposed to be detached."); // Check the ArgumentNullException Assert.Throws <ArgumentNullException>(() => testInst.GetSoundEffectController(null), "GetController did not throw ArgumentNullException."); } } }
public static AudioEmitterComponent GetSoundController(this AudioEmitterComponent audioEmitter, string key, out AudioEmitterSoundController soundController) { soundController = audioEmitter[key]; return(audioEmitter); }
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)); }
public override void Start() { if (ShootSource == null) { throw new ArgumentException("ShootSource not set"); } if (ShootTarget == null) { throw new ArgumentException("ShootTarget not set"); } if (Light == null) { throw new ArgumentException("Light not set"); } if (ShootTrail == null) { throw new ArgumentException("ShootTrail not set"); } if (ShootImpact == null) { throw new ArgumentException("ShootImpact not set"); } if (BulletHole == null) { throw new ArgumentException("BulletHole not set"); } var muzzleFlashEntity = ShootSource.FindChild("MuzzleFlash"); muzzleFlashParticles = muzzleFlashEntity?.Get <ParticleSystemComponent>()?.ParticleSystem; muzzleFlashParticles?.Stop(); laserEffect = ShootTrail.ParticleSystem; laserEffect.Stop(); laserImpact = ShootImpact.ParticleSystem; laserImpact.Stop(); BulletHole.ParticleSystem.Enabled = true; BulletHole.ParticleSystem.Stop(); Light.Enabled = false; AudioEmitterComponent shootEmitter = Entity.FindChild("ShootSource").Get <AudioEmitterComponent>(); AudioEmitterComponent shootTargetEmitter = ShootTarget.Get <AudioEmitterComponent>(); // Load different shoot sound effects shootSounds = new AudioEmitterSoundController[4]; for (int i = 0; i < shootSounds.Length; i++) { shootSounds[i] = shootEmitter["Shoot" + i]; } // Load different impact sound effects impactSounds = new AudioEmitterSoundController[4]; for (int i = 0; i < impactSounds.Length; i++) { impactSounds[i] = shootTargetEmitter["Impact" + i]; } SoldierWeapon weapon = Entity.Get <SoldierWeapon>(); weapon.OnShotFired += (soldierWeapon, result) => { Script.AddTask(async() => await FireWeapon(result)); }; }
/// <summary> /// Takes all sounds starting with <see cref="baseName"/> /// </summary> public RandomSoundSelector(AudioEmitterComponent emitter, string baseName) { this.emitter = emitter; Sounds = emitter.Sounds.Where(x => x.Key.StartsWith(baseName)).Select(x => emitter[x.Key]).ToArray(); }
public override void Update(float dt) { base.Update(dt); if ((count + 1) * (Self.Raging ? 0.7f : 1f) <= T) { count++; if (Self.Target == null || Self.Died) { return; } var a = Self.GetComponent <BkGraphicsComponent>(); Self.GetComponent <AudioEmitterComponent>().EmitRandomized("mob_oldking_shoot"); Tween.To(1.8f, a.Scale.X, x => a.Scale.X = x, 0.2f); Tween.To(0.2f, a.Scale.Y, x => a.Scale.Y = x, 0.2f).OnEnd = () => { Tween.To(1, a.Scale.X, x => a.Scale.X = x, 0.3f); Tween.To(1, a.Scale.Y, x => a.Scale.Y = x, 0.3f); if (Self.Target == null || Self.Died) { return; } var skull = Projectile.Make(Self, explode ? "skull" : "skup", Rnd.AnglePI(), explode ? Rnd.Float(5, 12) : 14); skull.CanBeReflected = false; skull.CanBeBroken = false; if (explode) { skull.NearDeath += p => { var c = new AudioEmitterComponent { DestroySounds = false }; p.AddComponent(c); c.Emit("mob_oldking_explode"); }; skull.OnDeath += (p, e, t) => { if (!t) { return; } for (var i = 0; i < 16; i++) { var bullet = Projectile.Make(Self, "small", ((float)i) / 8 * (float)Math.PI, (i % 2 == 0 ? 2 : 1) * 4 + 3); bullet.CanBeReflected = false; bullet.CanBeBroken = false; bullet.Center = p.Center; } }; } skull.Controller += TargetProjectileController.Make(Self.Target, 0.5f); skull.Range = 5f; skull.IndicateDeath = true; skull.CanBeReflected = false; skull.GetComponent <ProjectileGraphicsComponent>().IgnoreRotation = true; if (count == (Self.Raging ? 6 : 4)) { Self.Become <FightState>(); } }; } }
/// <summary> /// Adds a sound to the audio emitter. /// </summary> /// <remarks> /// It uses the name of the sound as key for the sound controller. So set the Name property of the sound to something meaningful before. /// </remarks> /// <param name="audioEmitter">The audio emitter.</param> /// <param name="sound">The sound.</param> /// <returns></returns> public static AudioEmitterComponent AddSound(this AudioEmitterComponent audioEmitter, Sound sound) { audioEmitter.Sounds[sound.Name] = sound; audioEmitter.AttachSound(sound); return(audioEmitter); }
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 void Start() { if (Entity.Transform.Parent != null) { throw new ArgumentException("SoldierController must be root"); } if (Camera == null) { throw new ArgumentException("Camera is not set"); } if (AnimationComponent == null) { throw new ArgumentException("AnimationComponent is not set"); } if (CameraController == null) { throw new ArgumentException("CameraController is not set"); } if (DroneCrosshair == null) { throw new ArgumentException("DroneCrosshair is not set"); } if (RotationSpeed < 0 || RotationSpeed > 1) { throw new ArgumentException("Rotation Speed must be between 0 and 1"); } //this.GetSimulation().ColliderShapesRendering = true; // Enable UI IStarbreach ipbrGame = Game as IStarbreach; //Entity statusBarEntity = ipbrGame.PlayerUiEntity.FindChild("StatusBar"); //uiComponent = statusBarEntity.Get<UIComponent>(); //uiComponent.Enabled = true; stateMachine = new FiniteStateMachine("SoldierController"); stateMachine.RegisterState(new State(IdleState) { UpdateMethod = UpdateIdle }); stateMachine.RegisterState(new State(RunState) { UpdateMethod = UpdateRun }); stateMachine.RegisterState(new State(WalkState) { EnterMethod = StartWalk, UpdateMethod = UpdateWalk }); stateMachine.Start(Script, IdleState); Instance = this; character = Entity.Get <CharacterComponent>(); sphereCastOrigin = Entity.FindChild("SphereCastOrigin"); AudioEmitterComponent emitter = Entity.Get <AudioEmitterComponent>(); // Load 3 different being hit sounds hitSounds = new AudioEmitterSoundController[3]; for (int i = 0; i < 3; i++) { hitSounds[i] = emitter["Hit" + i]; hitSounds[i].IsLooping = false; } deathSound = emitter["Death"]; }
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)); }
public static Entity AddAudioEmitter(this Entity entity, out AudioEmitterComponent audioEmitter) { audioEmitter = new AudioEmitterComponent(); entity.Add(audioEmitter); return(entity); }