public void UpdateBreakSounds() { if (Api.Side != EnumAppSide.Client) { return; } if (resistance > 0 && bebrake.Engaged && network != null && network.Speed > 0.1) { if (brakeSound == null || !brakeSound.IsPlaying) { brakeSound = ((IClientWorldAccessor)Api.World).LoadSound(new SoundParams() { Location = new AssetLocation("sounds/effect/woodgrind.ogg"), ShouldLoop = true, Position = Position.ToVec3f().Add(0.5f, 0.25f, 0.5f), DisposeOnFinish = false, Volume = 1 }); brakeSound.Start(); } brakeSound.SetPitch(GameMath.Clamp(network.Speed * 1.5f + 0.2f, 0.5f, 1)); } else { brakeSound?.FadeOut(1, (s) => { brakeSound.Stop(); }); } }
/// <summary> /// Fades out the current track. /// </summary> /// <param name="seconds">The duration of the fade out in seconds.</param> /// <param name="onFadedOut">What to have happen after the track has faded out.</param> public virtual void FadeOut(float seconds, Action onFadedOut = null) { loading = false; if (Sound != null && IsActive) { Sound.FadeOut(seconds, (sound) => { sound.Dispose(); Sound = null; onFadedOut?.Invoke(); }); return; } }
/// <summary> /// Fades out the current track. /// </summary> /// <param name="seconds">The duration of the fade out in seconds.</param> /// <param name="onFadedOut">What to have happen after the track has faded out.</param> public void FadeOut(float seconds, Action onFadedOut = null) { loading = false; if (Sound != null && IsActive) { Sound.FadeOut(seconds, (sound) => { sound.Dispose(); Sound = null; onFadedOut?.Invoke(); }); // Half cool down when interupted SetCooldown(0.5f); return; } // Full cooldown when stopped normally SetCooldown(1f); }
/// <summary> /// Delays behaviors from ticking to reduce flickering /// </summary> /// <param name="dt"></param> public override void OnGameTick(float dt) { // (1 - 0.95^(x/100)) / 2 // http://fooplot.com/#W3sidHlwZSI6MCwiZXEiOiIoMS0wLjk1Xih4LzEwMCkpLzIiLCJjb2xvciI6IiMwMDAwMDAifSx7InR5cGUiOjEwMDAsIndpbmRvdyI6WyIwIiwiMzAwMCIsIjAiLCIxIl19XQ-- if (physicsBh != null) { physicsBh.clientPhysicsTickTimeThreshold = (float)((1 - Math.Pow(0.95, particleSys.ActiveFallingBlocks / 100.0)) / 4.0); } if (soundStartDelay > 0) { soundStartDelay -= dt; if (soundStartDelay <= 0) { sound.Start(); } } if (sound != null) { sound.SetPosition((float)Pos.X, (float)Pos.Y, (float)Pos.Z); } if (lingerTicks > 0) { lingerTicks--; if (lingerTicks == 0) { if (Api.Side == EnumAppSide.Client && sound != null) { sound.FadeOut(3f, (s) => { s.Dispose(); }); } Die(); } return; } if (!Collided && !fallHandled) { nowDustIntensity = 1; //spawnParticles(0); } else { nowDustIntensity = 0; } ticksAlive++; if (ticksAlive >= 2 || Api.World.Side == EnumAppSide.Client) // Seems like we have to do it instantly on the client, otherwise we miss the OnChunkRetesselated Event { if (!InitialBlockRemoved) { InitialBlockRemoved = true; UpdateBlock(true, initialPos); } foreach (EntityBehavior behavior in SidedProperties.Behaviors) { behavior.OnGameTick(dt); } } pushaccum += dt; fallMotion.X *= 0.99f; fallMotion.Z *= 0.99f; if (pushaccum > 0.2f) { pushaccum = 0; if (!Collided) { Entity[] entities = World.GetEntitiesAround(SidedPos.XYZ, 1.1f, 1.1f, (e) => !(e is EntityBlockFalling)); for (int i = 0; i < entities.Length; i++) { if (Api.Side == EnumAppSide.Server || entities[i] is EntityPlayer) { entities[i].SidedPos.Motion.Add(fallMotion.X / 10f, 0, fallMotion.Z / 10f); } } } } if (Api.Side == EnumAppSide.Server && !Collided && World.Rand.NextDouble() < 0.01) { World.BlockAccessor.TriggerNeighbourBlockUpdate(ServerPos.AsBlockPos); } if (CollidedVertically && Pos.Motion.Length() == 0) { OnFallToGround(0); } }
/// <summary> /// Delays behaviors from ticking to reduce flickering /// </summary> /// <param name="dt"></param> public override void OnGameTick(float dt) { if (soundStartDelay > 0) { soundStartDelay -= dt; if (soundStartDelay <= 0) { sound.Start(); } } if (sound != null) { sound.SetPosition((float)Pos.X, (float)Pos.Y, (float)Pos.Z); } if (lingerTicks > 0) { lingerTicks--; if (lingerTicks == 0) { if (Api.Side == EnumAppSide.Client && sound != null) { sound.FadeOut(3f, (s) => { s.Dispose(); }); } Die(); } return; } if (!Collided && !fallHandled) { spawnParticles(0); } ticksAlive++; if (ticksAlive >= 2 || Api.World.Side == EnumAppSide.Client) // Seems like we have to do it instantly on the client, otherwise we miss the OnChunkRetesselated Event { if (!InitialBlockRemoved) { InitialBlockRemoved = true; UpdateBlock(true, initialPos); } foreach (EntityBehavior behavior in SidedProperties.Behaviors) { behavior.OnGameTick(dt); } } pushaccum += dt; fallMotion.X *= 0.99f; fallMotion.Z *= 0.99f; if (pushaccum > 0.2f) { pushaccum = 0; if (!Collided) { Entity[] entities = World.GetEntitiesAround(LocalPos.XYZ, 1.1f, 1.1f, (e) => !(e is EntityBlockFalling)); for (int i = 0; i < entities.Length; i++) { if (Api.Side == EnumAppSide.Server || entities[i] is EntityPlayer) { entities[i].LocalPos.Motion.Add(fallMotion.X / 10f, 0, fallMotion.Z / 10f); } } } } if (Api.Side == EnumAppSide.Server && !Collided && World.Rand.NextDouble() < 0.01) { World.BlockAccessor.TriggerNeighbourBlockUpdate(ServerPos.AsBlockPos); } if (CollidedVertically && Pos.Motion.Length() == 0) { OnFallToGround(0); } }