Иконка ресурса

FREE JumpScare : 1.0.0 1.0.0

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("JumpScare", "RustFlash", "1.0.0")]
    [Description("Halloween Jumpscare Plugin")]
    class JumpScare : RustPlugin
    {
        #region Fields
        [PluginReference] private Plugin ImageLibrary;
        
        private ConfigData configData;
        private Timer jumpscareTimer;
        private List<string> scareImages = new List<string>();
        private Dictionary<ulong, DateTime> lastJumpscare = new Dictionary<ulong, DateTime>();
        private const string JUMPSCARE_UI = "JumpScareUI";
        private string dataDirectory;
        private DateTime nextJumpscareTime;
        
        private const string PERMISSION_RECEIVE = "jumpscare.receive";
        #endregion

        #region Configuration
        private class ConfigData
        {
            public int JumpscareIntervalMinutes { get; set; } = 60;
            public float JumpscareDisplaySeconds { get; set; } = 3f;
            public float MinPlayersBetweenScares { get; set; } = 5f;
            public float MaxPlayersBetweenScares { get; set; } = 15f;
            public bool EnableSounds { get; set; } = true;
            public bool OnlyAtNight { get; set; } = true;
            public int MinPlayersOnline { get; set; } = 2;
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                configData = Config.ReadObject<ConfigData>();
                if (configData == null)
                    LoadDefaultConfig();
            }
            catch
            {
                LoadDefaultConfig();
            }
            SaveConfig();
        }

        protected override void LoadDefaultConfig()
        {
            configData = new ConfigData();
            Puts("Default configuration created.");
        }

        protected override void SaveConfig() => Config.WriteObject(configData);
        #endregion

        #region Oxide Hooks
        void Init()
        {
            dataDirectory = Path.Combine(Interface.Oxide.DataDirectory, "JumpScare");
            if (!Directory.Exists(dataDirectory))
            {
                Directory.CreateDirectory(dataDirectory);
                Puts($"Created JumpScare data directory: {dataDirectory}");
            }
            
            permission.RegisterPermission(PERMISSION_RECEIVE, this);
        }

        void OnServerInitialized()
        {
            if (ImageLibrary == null)
            {
                PrintError("ImageLibrary plugin not found! This plugin requires ImageLibrary to work.");
                return;
            }

            LoadScareImages();
            StartJumpscareTimer();
        }

        void Unload()
        {
            jumpscareTimer?.Destroy();
            
            foreach (BasePlayer player in BasePlayer.activePlayerList)
            {
                CuiHelper.DestroyUi(player, JUMPSCARE_UI);
            }
        }
        #endregion

        #region Core Functions
        private void LoadScareImages()
        {
            scareImages.Clear();
            
            string[] imageFiles = Directory.GetFiles(dataDirectory, "*.png")
                .Concat(Directory.GetFiles(dataDirectory, "*.jpg"))
                .Concat(Directory.GetFiles(dataDirectory, "*.jpeg"))
                .ToArray();

            if (imageFiles.Length == 0)
            {
                PrintWarning($"No images found in {dataDirectory}! Place your scare images there.");
                return;
            }

            foreach (string imagePath in imageFiles)
            {
                string fileName = Path.GetFileNameWithoutExtension(imagePath);
                scareImages.Add(fileName);
                
                byte[] imageData = File.ReadAllBytes(imagePath);
                ImageLibrary?.Call("AddImageData", fileName, imageData, 0UL);
            }

            Puts($"Loaded {scareImages.Count} scare images.");
        }

        private void StartJumpscareTimer()
        {
            jumpscareTimer?.Destroy();
            
            float nextScare = UnityEngine.Random.Range(configData.MinPlayersBetweenScares, configData.MaxPlayersBetweenScares) * 60f;
            nextJumpscareTime = DateTime.Now.AddSeconds(nextScare);
            
            jumpscareTimer = timer.Once(nextScare, () =>
            {
                TriggerRandomJumpscare();
                StartJumpscareTimer();
            });
        }

        private void TriggerRandomJumpscare()
        {
            if (BasePlayer.activePlayerList.Count < configData.MinPlayersOnline)
                return;

            if (configData.OnlyAtNight && !IsNightTime())
                return;

            if (scareImages.Count == 0)
            {
                PrintWarning("No scare images available!");
                return;
            }

            var eligiblePlayers = BasePlayer.activePlayerList.Where(p => 
                permission.UserHasPermission(p.UserIDString, PERMISSION_RECEIVE) &&
                (!lastJumpscare.ContainsKey(p.userID) || 
                (DateTime.Now - lastJumpscare[p.userID]).TotalMinutes >= configData.JumpscareIntervalMinutes)
            ).ToList();

            if (eligiblePlayers.Count == 0)
                return;

            BasePlayer targetPlayer = eligiblePlayers[UnityEngine.Random.Range(0, eligiblePlayers.Count)];
            string randomImage = scareImages[UnityEngine.Random.Range(0, scareImages.Count)];

            ExecuteJumpscare(targetPlayer, randomImage);
            lastJumpscare[targetPlayer.userID] = DateTime.Now;
        }

        private void ExecuteJumpscare(BasePlayer player, string imageName)
        {
            if (player == null || !player.IsConnected)
                return;

            if (configData.EnableSounds)
            {
                PlayWorkingScareSound(player);
            }

            ShowJumpscareImage(player, imageName);

            player.ChatMessage("<color=red><size=16>:scarecrowhead: You got jumpscared! Happy Halloween :exclamation:</size></color>");

            timer.Once(configData.JumpscareDisplaySeconds, () =>
            {
                if (player != null && player.IsConnected)
                {
                    CuiHelper.DestroyUi(player, JUMPSCARE_UI);
                }
            });
        }

        private void PlayWorkingScareSound(BasePlayer player)
        {
            try
            {
                string[] bothSounds = new string[]
                {
                    "assets/bundled/prefabs/fx/player/beartrap_scream.prefab", 
                    "assets/bundled/prefabs/fx/player/howl.prefab"
                };

                foreach(string soundPath in bothSounds)
                {
                    Effect effect = new Effect(soundPath, player.transform.position, Vector3.up);
                    EffectNetwork.Send(effect, player.Connection);
                }
            }
            catch (Exception ex)
            {
                PrintWarning($"Failed to play scare sounds: {ex.Message}");
            }
        }

        private void PlayScareSound(BasePlayer player)
        {
            PlayWorkingScareSound(player);
        }

        private void ShowJumpscareImage(BasePlayer player, string imageName)
        {
            string imageId = ImageLibrary?.Call<string>("GetImage", imageName, 0UL) as string;
            
            if (string.IsNullOrEmpty(imageId))
            {
                PrintWarning($"Failed to get image ID for {imageName}");
                return;
            }

            var container = new CuiElementContainer();
            
            container.Add(new CuiPanel
            {
                Image = { Color = "0 0 0 0.95" },
                RectTransform = { AnchorMin = "0 0", AnchorMax = "1 1" }
            }, "Overlay", JUMPSCARE_UI);
            
            container.Add(new CuiElement
            {
                Parent = JUMPSCARE_UI,
                Components =
                {
                    new CuiRawImageComponent { Png = imageId },
                    new CuiRectTransformComponent { AnchorMin = "0 0", AnchorMax = "1 1" }
                }
            });

            CuiHelper.AddUi(player, container);
        }

        private bool IsNightTime()
        {
            float currentTime = TOD_Sky.Instance.Cycle.Hour;
            return currentTime >= 20f || currentTime <= 6f;
        }
        #endregion

        #region Commands
        [ChatCommand("scare")]
        private void CmdScare(BasePlayer player, string command, string[] args)
        {
            if (!player.IsAdmin)
            {
                player.ChatMessage("No permission.");
                return;
            }

            if (args.Length == 0)
            {
                if (scareImages.Count == 0)
                {
                    player.ChatMessage("No scare images available!");
                    return;
                }
                
                string randomImage = scareImages[UnityEngine.Random.Range(0, scareImages.Count)];
                ExecuteJumpscare(player, randomImage);
            }
            else if (args.Length == 1)
            {
                BasePlayer target = BasePlayer.Find(args[0]);
                if (target == null)
                {
                    player.ChatMessage("Player not found.");
                    return;
                }
                
                if (scareImages.Count == 0)
                {
                    player.ChatMessage("No scare images available!");
                    return;
                }
                
                string randomImage = scareImages[UnityEngine.Random.Range(0, scareImages.Count)];
                ExecuteJumpscare(target, randomImage);
            }
        }

        [ChatCommand("scareinfo")]
        private void CmdScareInfo(BasePlayer player, string command, string[] args)
        {
            if (!player.IsAdmin)
            {
                player.ChatMessage("No permission.");
                return;
            }

            string nextScareInfo;
            if (jumpscareTimer != null && nextJumpscareTime > DateTime.Now)
            {
                double secondsUntilNext = (nextJumpscareTime - DateTime.Now).TotalSeconds;
                nextScareInfo = $"{secondsUntilNext:F0} seconds";
            }
            else
            {
                nextScareInfo = "Timer not active";
            }

            string imageList = scareImages.Count > 0 ? string.Join(", ", scareImages) : "None loaded";

            string infoMessage = $"<color=orange><size=14> :pumpkin: JumpScare Info  :pumpkin:</size></color>\n" +
                               $"<color=white>Loaded Images: <color=yellow>{scareImages.Count}</color></color>\n" +
                               $"<color=white>Next Scare: <color=yellow>{nextScareInfo}</color></color>\n" +
                               $"<color=white>Images: <color=yellow>{imageList}</color></color>";

            player.ChatMessage(infoMessage);
        }

        [ChatCommand("reloadscares")]
        private void CmdReloadScares(BasePlayer player, string command, string[] args)
        {
            if (!player.IsAdmin)
            {
                player.ChatMessage("No permission.");
                return;
            }

            LoadScareImages();
            player.ChatMessage($"Reloaded {scareImages.Count} scare images.");
        }
        #endregion
    }
}

Автор
15FPS
Скачиваний
0
Просмотры
1
Первый выпуск
Обновление
Оценка
0.00 звёзд 0 оценок
Сверху