Esempio n. 1
0
        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);

            RegisterGameTickListener(OnTick, 25);
            RegisterGameTickListener(OnSlowTick, 1000);

            fireBlock = api.World.GetBlock(new AssetLocation("fire"));
            if (fireBlock == null)
            {
                fireBlock = new Block();
            }

            neibBlock = api.World.BlockAccessor.GetBlock(Pos.AddCopy(fromFacing.Opposite));
            wsys      = api.ModLoader.GetModSystem <WeatherSystemBase>();

            if (ambientSound == null && api.Side == EnumAppSide.Client)
            {
                ambientSound = ((IClientWorldAccessor)api.World).LoadSound(new SoundParams()
                {
                    Location        = new AssetLocation("sounds/environment/fire.ogg"),
                    ShouldLoop      = true,
                    Position        = Pos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                    DisposeOnFinish = false,
                    Volume          = 1f
                });

                if (ambientSound != null)
                {
                    ambientSound.PlaybackPosition = ambientSound.SoundLengthSeconds * (float)Api.World.Rand.NextDouble();
                    ambientSound.Start();
                }
            }
        }
        private void initSoundsAndTicking()
        {
            fuelBlock = Api.World.BlockAccessor.GetBlock(FuelPos);

            l1 = Blockentity.RegisterGameTickListener(OnTick, 25);
            if (Api.Side == EnumAppSide.Server)
            {
                l2 = Blockentity.RegisterGameTickListener(OnSlowServerTick, 1000);
            }

            wsys = Api.ModLoader.GetModSystem <WeatherSystemBase>();

            if (ambientSound == null && Api.Side == EnumAppSide.Client)
            {
                ambientSound = ((IClientWorldAccessor)Api.World).LoadSound(new SoundParams()
                {
                    Location        = new AssetLocation("sounds/environment/fire.ogg"),
                    ShouldLoop      = true,
                    Position        = FirePos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                    DisposeOnFinish = false,
                    Volume          = 1f
                });

                if (ambientSound != null)
                {
                    ambientSound.PlaybackPosition = ambientSound.SoundLengthSeconds * (float)Api.World.Rand.NextDouble();
                    ambientSound.Start();
                }
            }

            particleFacing = BlockFacing.FromNormal(new Vec3i(FirePos.X - FuelPos.X, FirePos.Y - FuelPos.Y, FirePos.Z - FuelPos.Z));
        }
        public void ToggleAmbientSounds(bool on)
        {
            if (Api.Side != EnumAppSide.Client)
            {
                return;
            }

            if (on)
            {
                if (ambientSound == null || !ambientSound.IsPlaying)
                {
                    ambientSound = ((IClientWorldAccessor)Api.World).LoadSound(new SoundParams()
                    {
                        Location        = new AssetLocation("sounds/environment/fireplace.ogg"),
                        ShouldLoop      = true,
                        Position        = be.Pos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                        DisposeOnFinish = false,
                        Volume          = SoundLevel
                    });

                    if (ambientSound != null)
                    {
                        ambientSound.Start();
                        ambientSound.PlaybackPosition = ambientSound.SoundLengthSeconds * (float)Api.World.Rand.NextDouble();
                    }
                }
            }
            else
            {
                ambientSound?.Stop();
                ambientSound?.Dispose();
                ambientSound = null;
            }
        }
Esempio n. 4
0
        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);

            RegisterGameTickListener(OnTick, 50);


            if (fuseSound == null && api.Side == EnumAppSide.Client)
            {
                fuseSound = ((IClientWorldAccessor)api.World).LoadSound(new SoundParams()
                {
                    Location        = new AssetLocation("sounds/effect/fuse"),
                    ShouldLoop      = true,
                    Position        = pos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                    DisposeOnFinish = false,
                    Volume          = 0.1f,
                    Range           = 16,
                });
            }

            block        = api.World.BlockAccessor.GetBlock(pos);
            blastRadius  = block.Attributes["blastRadius"].AsInt(4);
            injureRadius = block.Attributes["injureRadius"].AsInt(8);
            blastType    = (EnumBlastType)block.Attributes["blastType"].AsInt((int)EnumBlastType.OreBlast);
        }
Esempio n. 5
0
        public virtual void ToggleAmbientSounds(bool on)
        {
            if (Api.Side != EnumAppSide.Client)
            {
                return;
            }

            if (on)
            {
                if (ambientSound == null || !ambientSound.IsPlaying)
                {
                    ambientSound = ((IClientWorldAccessor)Api.World).LoadSound(new SoundParams()
                    {
                        Location        = new AssetLocation("sounds/environment/fireplace.ogg"),
                        ShouldLoop      = true,
                        Position        = Pos.ToVec3f().Add(0.5f, 0.1f, 0.5f),
                        DisposeOnFinish = false,
                        Volume          = 0.66f
                    });

                    ambientSound.Start();
                }
            }
            else
            {
                ambientSound.Stop();
                ambientSound.Dispose();
                ambientSound = null;
            }
        }
Esempio n. 6
0
        private void onTrackLoaded(ILoadedSound sound)
        {
            if (track == null)
            {
                sound?.Dispose();
                return;
            }
            if (sound == null)
            {
                return;
            }

            track.Sound = sound;

            // Needed so that the music engine does not dispose the sound
            Api.Event.EnqueueMainThreadTask(() => track.loading = true, "settrackloading");

            long longMsPassed = Api.World.ElapsedMilliseconds - startLoadingMs;

            handlerId = RegisterDelayedCallback((dt) => {
                if (sound.IsDisposed)
                {
                    Api.World.Logger.Notification("Echo chamber track is diposed? o.O");
                }

                if (!wasStopped)
                {
                    sound.Start();
                }

                track.loading = false;
            }, (int)Math.Max(0, 500 - longMsPassed));
        }
Esempio n. 7
0
        public override void OnReceivedServerPacket(int packetid, byte[] data)
        {
            if (packetid == 1025)
            {
                AssetLocation loc = SerializerUtil.Deserialize <AssetLocation>(data);

                if (alarmSound == null)
                {
                    alarmSound = capi.World.LoadSound(new SoundParams()
                    {
                        Location        = loc,
                        Position        = Pos.XYZ.ToVec3f(),
                        Range           = 48,
                        ShouldLoop      = true,
                        SoundType       = EnumSoundType.Sound,
                        Volume          = 0,
                        DisposeOnFinish = false
                    });
                }

                if (!alarmSound.IsPlaying)
                {
                    alarmSound.Start();
                    alarmSound.FadeIn(0.25f, null);
                }
            }

            if (packetid == 1026)
            {
                alarmSound?.FadeOutAndStop(0.25f);
            }

            base.OnReceivedServerPacket(packetid, data);
        }
Esempio n. 8
0
        public void PlaySound(float startPitch, float endPitch, float volume)
        {
            startPitch *= pitchModifier;
            endPitch   *= pitchModifier;
            volume     *= volumneModifier;

            SoundParams param = new SoundParams()
            {
                Location        = soundName,
                DisposeOnFinish = true,
                Pitch           = startPitch,
                Volume          = volume,
                Position        = entity.Pos.XYZ.ToVec3f().Add(0, (float)entity.EyeHeight, 0),
                ShouldLoop      = false,
                Range           = 8,
            };

            ILoadedSound sound = capi.World.LoadSound(param);

            if (startPitch != endPitch)
            {
                slidingPitchSounds.Add(new SlidingPitchSound()
                {
                    startPitch = startPitch,
                    endPitch   = endPitch,
                    sound      = sound,
                    startMs    = capi.World.ElapsedMilliseconds
                });
            }


            sound.Start();
        }
Esempio n. 9
0
        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);


            if (api.Side == EnumAppSide.Server)
            {
                ICoreServerAPI sapi = api as ICoreServerAPI;

                tpLocation = manager.GetOrCreateLocation(Pos);

                RegisterGameTickListener(OnServerGameTick, 50);
            }
            else
            {
                RegisterGameTickListener(OnClientGameTick, 50);

                teleportingSound = (api as ICoreClientAPI).World.LoadSound(new SoundParams()
                {
                    Location         = new AssetLocation("sounds/block/teleporter.ogg"),
                    ShouldLoop       = true,
                    Position         = Pos.ToVec3f(),
                    RelativePosition = false,
                    DisposeOnFinish  = false,
                    Volume           = 0.5f
                });
            }

            ownBlock = Block as BlockTeleporter;
            posvec   = new Vec3d(Pos.X, Pos.Y + 1, Pos.Z);
        }
Esempio n. 10
0
        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);

            bloomeryInv.LateInitialize("bloomery-1", api);

            RegisterGameTickListener(OnGameTick, 100);

            if (ambientSound == null && api.Side == EnumAppSide.Client)
            {
                ambientSound = ((IClientWorldAccessor)api.World).LoadSound(new SoundParams()
                {
                    Location        = new AssetLocation("sounds/environment/fire.ogg"),
                    ShouldLoop      = true,
                    Position        = Pos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                    DisposeOnFinish = false,
                    Volume          = 0.3f,
                    Range           = 8
                });
                if (burning)
                {
                    ambientSound.Start();
                }
            }

            if (api.Side == EnumAppSide.Client)
            {
                ICoreClientAPI capi = (ICoreClientAPI)api;
                capi.Event.RegisterRenderer(renderer = new BloomeryContentsRenderer(Pos, capi), EnumRenderStage.Opaque, "bloomery");

                UpdateRenderer();
            }

            ownFacing = BlockFacing.FromCode(api.World.BlockAccessor.GetBlock(Pos).LastCodePart());
        }
Esempio n. 11
0
        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(); });
            }
        }
Esempio n. 12
0
        void updateBurningState()
        {
            if (!burning)
            {
                return;
            }

            if (Api.World.Side == EnumAppSide.Client)
            {
                if (ambientSound == null || !ambientSound.IsPlaying)
                {
                    ambientSound = ((IClientWorldAccessor)Api.World).LoadSound(new SoundParams()
                    {
                        Location        = new AssetLocation("sounds/effect/embers.ogg"),
                        ShouldLoop      = true,
                        Position        = Pos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                        DisposeOnFinish = false,
                        Volume          = 1
                    });

                    if (ambientSound != null)
                    {
                        ambientSound.PlaybackPosition = ambientSound.SoundLengthSeconds * (float)Api.World.Rand.NextDouble();
                        ambientSound.Start();
                    }
                }

                listenerId = RegisterGameTickListener(onBurningTickClient, 100);
            }
            else
            {
                listenerId = RegisterGameTickListener(onBurningTickServer, 10000);
            }
        }
Esempio n. 13
0
        public override bool OnHeldInteractStep(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
        {
            if (blockSel == null || !(byEntity is EntityPlayer))
            {
                return(false);
            }

            FpHandTransform.Rotation.Y = GameMath.Mod(byEntity.World.ElapsedMilliseconds / (50f - secondsUsed * 20), 360);
            TpHandTransform.Rotation.Y = GameMath.Mod(byEntity.World.ElapsedMilliseconds / (50f - secondsUsed * 20), 360);

            if (byEntity.World is IClientWorldAccessor)
            {
                particlesHeld.MinQuantity = 1;

                Vec3d pos = blockSel.Position.ToVec3d().Add(blockSel.HitPosition);
                SpawnParticles(byEntity.World, pos, false);

                (byEntity.World as IClientWorldAccessor).AddCameraShake(0.035f);


                ILoadedSound sound = ObjectCacheUtil.TryGet <ILoadedSound>(api, "temporalGearSound");
                sound?.SetPitch(0.7f + secondsUsed / 4);
            }

            return(secondsUsed < 3.5);
        }
Esempio n. 14
0
        public override void StartClientSide(ICoreClientAPI api)
        {
            capi = api;
            api.Event.RegisterEventBusListener(OnConfigEventClient, 0.5, "configTeleporter");

            clientChannel =
                api.Network.RegisterChannel("tpManager")
                .RegisterMessageType(typeof(TpLocations))
                .RegisterMessageType(typeof(TeleporterLocation))
                .SetMessageHandler <TpLocations>(OnLocationsReceived)
            ;

            if (teleportingSound == null)
            {
                teleportingSound = ((IClientWorldAccessor)api.World).LoadSound(new SoundParams()
                {
                    Location         = new AssetLocation("sounds/block/teleporter.ogg"),
                    ShouldLoop       = true,
                    Position         = null,
                    RelativePosition = true,
                    DisposeOnFinish  = false,
                    Volume           = 1
                });
            }

            api.Event.RegisterGameTickListener(OnClientTick, 50);
            api.Event.LeaveWorld += () => teleportingSound?.Dispose();
        }
Esempio n. 15
0
        private void onClientTick(float dt)
        {
            if (!riftsEnabled)
            {
                return;
            }

            Vec3d plrPos = capi.World.Player.Entity.Pos.XYZ;

            nearestRifts = rifts.OrderBy(rift => rift.Position.SquareDistanceTo(plrPos)).ToArray();

            for (int i = 0; i < Math.Min(4, nearestRifts.Length); i++)
            {
                Rift         rift  = nearestRifts[i];
                ILoadedSound sound = riftSounds[i];
                if (!sound.IsPlaying)
                {
                    sound.Start();
                    sound.PlaybackPosition = sound.SoundLengthSeconds * (float)capi.World.Rand.NextDouble();
                }

                sound.SetVolume(GameMath.Clamp(rift.GetNowSize(capi) / 3f, 0.1f, 1f));
                sound.SetPosition((float)rift.Position.X, (float)rift.Position.Y, (float)rift.Position.Z);
            }

            for (int i = nearestRifts.Length; i < 4; i++)
            {
                if (riftSounds[i].IsPlaying)
                {
                    riftSounds[i].Stop();
                }
            }
        }
 public void SetCookingSoundVolume(float volume)
 {
     if (volume > 0)
     {
         if (cookingSound == null)
         {
             cookingSound = capi.World.LoadSound(new SoundParams()
             {
                 Location        = new AssetLocation("sounds/effect/cooking.ogg"),
                 ShouldLoop      = true,
                 Position        = pos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                 DisposeOnFinish = false,
                 Volume          = volume
             });
             cookingSound.Start();
         }
         else
         {
             cookingSound.SetVolume(volume);
         }
     }
     else
     {
         if (cookingSound != null)
         {
             cookingSound.Stop();
             cookingSound.Dispose();
             cookingSound = null;
         }
     }
 }
Esempio n. 17
0
        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);

            RegisterGameTickListener(OnTick, 25);
            RegisterGameTickListener(OnSlowTick, 1000);

            fireBlock = api.World.GetBlock(new AssetLocation("fire"));
            if (fireBlock == null)
            {
                fireBlock = new Block();
            }

            neibBlock = api.World.BlockAccessor.GetBlock(pos.AddCopy(fromFacing.GetOpposite()));


            if (ambientSound == null && api.Side == EnumAppSide.Client)
            {
                RegisterDelayedCallback((dt) => {
                    // When the world loads with a lot of fire they'll all start at the same millisecond, so lets delay a bit
                    ambientSound = ((IClientWorldAccessor)api.World).LoadSound(new SoundParams()
                    {
                        Location        = new AssetLocation("sounds/environment/fire.ogg"),
                        ShouldLoop      = true,
                        Position        = pos.ToVec3f().Add(0.5f, 0.25f, 0.5f),
                        DisposeOnFinish = false,
                        Volume          = 1f
                    });
                    ambientSound?.Start();
                }, api.World.Rand.Next(200));
            }
        }
        public override void Initialize(ICoreAPI api)
        {
            base.Initialize(api);

            if (FullyRepaired)
            {
                setupGameTickers();
            }

            ownBlock = Block as BlockStaticTranslocator;
            posvec   = new Vec3d(Pos.X + 0.5, Pos.Y, Pos.Z + 0.5);

            if (api.World.Side == EnumAppSide.Client)
            {
                float rotY = Block.Shape.rotateY;
                animUtil.InitializeAnimator("translocator", new Vec3f(0, rotY, 0));

                translocatingSound = (api as ICoreClientAPI).World.LoadSound(new SoundParams()
                {
                    Location         = new AssetLocation("sounds/effect/translocate-active.ogg"),
                    ShouldLoop       = true,
                    Position         = Pos.ToVec3f(),
                    RelativePosition = false,
                    DisposeOnFinish  = false,
                    Volume           = 0.5f
                });
            }
        }
Esempio n. 19
0
        private void Event_BlockTexturesLoaded()
        {
            if (teleportingSound == null)
            {
                teleportingSound = capi.World.LoadSound(new SoundParams()
                {
                    Location         = new AssetLocation("sounds/block/teleporter.ogg"),
                    ShouldLoop       = true,
                    Position         = null,
                    RelativePosition = true,
                    DisposeOnFinish  = false,
                    Volume           = 0.5f
                });
            }

            if (translocatingSound == null)
            {
                translocatingSound = capi.World.LoadSound(new SoundParams()
                {
                    Location         = new AssetLocation("sounds/effect/translocate-active.ogg"),
                    ShouldLoop       = true,
                    Position         = null,
                    RelativePosition = true,
                    DisposeOnFinish  = false,
                    Volume           = 0.5f
                });
            }
        }
Esempio n. 20
0
        public override void OnHeldInteractStop(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
        {
            pouringLoop?.Stop();
            pouringLoop?.Dispose();
            pouringLoop = null;

            slot.MarkDirty();
        }
Esempio n. 21
0
 public override bool OnHeldInteractCancel(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, EnumItemUseCancelReason cancelReason)
 {
     if (api.Side == EnumAppSide.Client)
     {
         sound?.Stop();
         sound = null;
     }
     return(true);
 }
 void killAmbientSound()
 {
     if (ambientSound != null)
     {
         ambientSound?.Stop();
         ambientSound?.Dispose();
         ambientSound = null;
     }
 }
Esempio n. 23
0
        public override bool OnHeldInteractCancel(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, EnumItemUseCancelReason cancelReason)
        {
            if (byEntity.World.Side == EnumAppSide.Client)
            {
                ILoadedSound sound = ObjectCacheUtil.TryGet <ILoadedSound>(api, "temporalGearSound");
                sound?.Stop();
                sound?.Dispose();
            }

            return(true);
        }
Esempio n. 24
0
        public override void OnBlockRemoved()
        {
            base.OnBlockRemoved();

            if (ambientSound != null)
            {
                ambientSound?.Stop();
                ambientSound?.Dispose();
                ambientSound = null;
            }
        }
Esempio n. 25
0
        /// <summary>
        /// Is it cool for the current track to continue playing?
        /// </summary>
        /// <param name="dt">Delta Time/Change in time.</param>
        /// <param name="props">Track properties.</param>
        /// <returns>Cool or not cool?</returns>
        public virtual bool ContinuePlay(float dt, TrackedPlayerProperties props)
        {
            if (!IsActive)
            {
                Sound?.Dispose();
                Sound = null;
                return(false);
            }

            return(docontinue);
        }
        public override void Initialize(EntityProperties properties, ICoreAPI api, long InChunkIndex3d)
        {
            if (removedBlockentity != null)
            {
                this.blockEntityAttributes = new TreeAttribute();
                removedBlockentity.ToTreeAttributes(blockEntityAttributes);
                blockEntityClass = api.World.ClassRegistry.GetBlockEntityClass(removedBlockentity.GetType());
            }

            SimulationRange = (int)(0.75f * GlobalConstants.DefaultTrackingRange);
            base.Initialize(properties, api, InChunkIndex3d);

            // Need to capture this now before we remove the block and start to fall
            drops = Block.GetDrops(api.World, initialPos, null);

            lightHsv = Block.GetLightHsv(World.BlockAccessor, initialPos);

            SidedPos.Motion.Y = -0.02;
            blockAsStack      = new ItemStack(Block);


            if (api.Side == EnumAppSide.Client && fallSound != null && fallingNow.Count < 100)
            {
                fallingNow.Add(EntityId);
                ICoreClientAPI capi = api as ICoreClientAPI;
                sound = capi.World.LoadSound(new SoundParams()
                {
                    Location  = fallSound.WithPathPrefixOnce("sounds/").WithPathAppendixOnce(".ogg"),
                    Position  = new Vec3f((float)Pos.X, (float)Pos.Y, (float)Pos.Z),
                    Range     = 32,
                    Pitch     = 0.8f + (float)capi.World.Rand.NextDouble() * 0.3f,
                    Volume    = 1,
                    SoundType = EnumSoundType.Ambient
                });
                sound.Start();
                soundStartDelay = 0.05f + (float)capi.World.Rand.NextDouble() / 3f;
            }

            canFallSideways = WatchedAttributes.GetBool("canFallSideways");
            dustIntensity   = WatchedAttributes.GetFloat("dustIntensity");


            if (WatchedAttributes.HasAttribute("fallSound"))
            {
                fallSound = new AssetLocation(WatchedAttributes.GetString("fallSound"));
            }

            if (api.World.Side == EnumAppSide.Client)
            {
                particleSys = api.ModLoader.GetModSystem <FallingBlockParticlesModSystem>();
                particleSys.Register(this);
                physicsBh = GetBehavior <EntityBehaviorPassivePhysics>();
            }
        }
Esempio n. 27
0
        public override bool OnHeldInteractCancel(float secondsUsed, IItemSlot slot, IEntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel, EnumItemUseCancelReason cancelReason)
        {
            if (byEntity.World.Side == EnumAppSide.Client)
            {
                ILoadedSound sound = byEntity.World.Api.ObjectCache["temporalGearSound"] as ILoadedSound;
                sound?.Stop();
                sound?.Dispose();
                // Console.WriteLine("sound stop");
            }

            return(true);
        }
Esempio n. 28
0
        /// <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;
            }
        }
Esempio n. 29
0
        /// <summary>
        /// Is it cool for the current track to continue playing?
        /// </summary>
        /// <param name="dt">Delta Time/Change in time.</param>
        /// <param name="props">Track properties.</param>
        /// <returns>Cool or not cool?</returns>
        public bool ContinuePlay(float dt, TrackedPlayerProperties props)
        {
            if (!IsActive)
            {
                Sound?.Dispose();
                Sound = null;
                SetCooldown(1f);
                return(false);
            }

            if (!ShouldPlayMusic)
            {
                FadeOut(3);
            }

            return(true);
        }
Esempio n. 30
0
        public override void OnHeldInteractStop(float secondsUsed, ItemSlot slot, EntityAgent byEntity, BlockSelection blockSel, EntitySelection entitySel)
        {
            if (byEntity.World.Side == EnumAppSide.Client)
            {
                ILoadedSound sound = ObjectCacheUtil.TryGet <ILoadedSound>(api, "temporalGearSound");
                sound?.Stop();
                sound?.Dispose();
            }

            if (blockSel == null || secondsUsed < 3.45)
            {
                return;
            }

            slot.TakeOut(1);
            slot.MarkDirty();
            //(byEntity as EntityPlayer)?.Player?.InventoryManager.BroadcastHotbarSlot();

            if (byEntity.World.Side == EnumAppSide.Client)
            {
                byEntity.World.PlaySoundAt(new AssetLocation("sounds/effect/portal.ogg"), byEntity, null, false);

                particlesHeld.MinSize     = 0.25f;
                particlesHeld.MaxSize     = 0.5f;
                particlesHeld.MinQuantity = 300;
                Vec3d pos = blockSel.Position.ToVec3d().Add(blockSel.HitPosition);
                SpawnParticles(byEntity.World, pos, true);
            }

            if (byEntity.World.Side == EnumAppSide.Server && byEntity is EntityPlayer)
            {
                IServerPlayer plr = byEntity.World.PlayerByUid((byEntity as EntityPlayer).PlayerUID) as IServerPlayer;

                int uses = api.World.Config.GetString("temporalGearRespawnUses", "-1").ToInt();
                plr.SetSpawnPosition(new PlayerSpawnPos()
                {
                    x             = byEntity.ServerPos.XYZInt.X,
                    y             = byEntity.ServerPos.XYZInt.Y,
                    z             = byEntity.ServerPos.XYZInt.Z,
                    yaw           = byEntity.ServerPos.Yaw,
                    pitch         = byEntity.ServerPos.Pitch,
                    RemainingUses = uses
                });
            }
        }