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

FREE RadiationZone : 1.0.0 1.0.0

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

namespace Oxide.Plugins
{
    [Info("Radiation Zone", "0killrest", "1.0.0")]
    [Description("High-risk radiation zone with rewards for survival")]
    internal class RadiationZone : RustPlugin
    {
        #region Configuration
        private static ConfigData config;
        
        private class ConfigData
        {
            public bool Enabled { get; set; } = true;
            public float ZoneRadius { get; set; } = 50f;
            public Vector3 ZoneCenter { get; set; } = new Vector3(0, 0, 0);
            public int RadiationPerSecond { get; set; } = 15;
            public int PointsPerSecond { get; set; } = 1;
            public bool ShowZoneOnMap { get; set; } = true;
            public string ZoneMarkerName { get; set; } = "radiation_zone";
            public List<RewardItem> Rewards { get; set; }

            public ConfigData()
            {
                Rewards = new List<RewardItem>
                {
                    new RewardItem { ShortName = "scrap", Amount = 50, PointsCost = 100, DisplayName = "Scrap x50" },
                    new RewardItem { ShortName = "metal.refined", Amount = 20, PointsCost = 80, DisplayName = "Metal Fragments x20" },
                    new RewardItem { ShortName = "sulfur", Amount = 30, PointsCost = 90, DisplayName = "Sulfur x30" },
                    new RewardItem { ShortName = "cloth", Amount = 50, PointsCost = 40, DisplayName = "Cloth x50" },
                    new RewardItem { ShortName = "rifle.ak", Amount = 1, PointsCost = 500, DisplayName = "AK-47" }
                };
            }
        }

        public class RewardItem
        {
            public string ShortName { get; set; }
            public int Amount { get; set; }
            public int PointsCost { get; set; }
            public string DisplayName { get; set; }
        }
        
        protected override void LoadConfig()
        {
            base.LoadConfig();
            config = Config.ReadObject<ConfigData>();
            if (config == null)
            {
                LoadDefaultConfig();
            }
        }
        
        protected override void LoadDefaultConfig()
        {
            config = new ConfigData();
            PrintWarning("Default configuration created.Edit it in oxide/config/RadiationZone.json");
            PrintWarning("Don't forget to set ZoneCenter coordinates for your map!");
            SaveConfig();
        }
        
        protected override void SaveConfig() => Config.WriteObject(config);
        #endregion

        #region Data Storage
        private Dictionary<ulong, PlayerZoneData> playerData;
        
        private class PlayerZoneData
        {
            public int Points { get; set; } = 0;
            public bool IsInZone { get; set; } = false;
            public float LastTickTime { get; set; } = 0f;
        }
        
        private void LoadData()
        {
            playerData = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<ulong, PlayerZoneData>>("RadiationZone_Data") ?? new Dictionary<ulong, PlayerZoneData>();
        }
        
        private void SaveData()
        {
            Interface.Oxide.DataFileSystem.WriteObject("RadiationZone_Data", playerData);
        }
        #endregion

        #region Hooks
        private GameObject markerObject;
        private Dictionary<ulong, Timer> radiationTimers = new Dictionary<ulong, Timer>();
        
        private void Init()
        {
            LoadData();
            permission.RegisterPermission("radiationzone.admin", this);
        }
        
        private void OnServerInitialized()
        {
            if (config.Enabled && config.ShowZoneOnMap)
            {
                CreateMapMarker();
            }
        }
        
        private void Unload()
        {
            if (markerObject != null)
                UnityEngine.Object.Destroy(markerObject);
                
            foreach (var timer in radiationTimers.Values)
            {
                timer?.Destroy();
            }
            radiationTimers.Clear();
            SaveData();
        }
        
        private void OnServerSave() => SaveData();
        
        private void OnPlayerTick(BasePlayer player, float deltaTime)
        {
            if (!config.Enabled) return;
            if (player == null || player.IsDead()) return;
            
            bool isInZone = IsPlayerInZone(player);
            
            if (!playerData.ContainsKey(player.userID))
            {
                playerData[player.userID] = new PlayerZoneData();
            }
            
            var data = playerData[player.userID];
            
            if (isInZone && !data.IsInZone)
            {
                // Entered zone
                data.IsInZone = true;
                SendReply(player, $"<color=red>⚠️ You entered the RADIATION ZONE!</color> You receive {config.PointsPerSecond} points per second.Use <color=yellow>/zone rewards</color> to spend points.");
                StartRadiationTimer(player);
            }
            else if (!isInZone && data.IsInZone)
            {
                // Exited zone
                data.IsInZone = false;
                SendReply(player, $"<color=green>You left the radiation zone.You have {data.Points} points saved!</color>");
                StopRadiationTimer(player);
                // Heal radiation slowly
                player.metabolism.radiation_poison.value = Math.Max(0, player.metabolism.radiation_poison.value - 5);
            }
            
            // Accumulate points while in zone
            if (data.IsInZone)
            {
                if (Time.realtimeSinceStartup - data.LastTickTime >= 1.0f)
                {
                    data.LastTickTime = Time.realtimeSinceStartup;
                    
                    // Apply radiation damage
                    player.metabolism.radiation_poison.value += config.RadiationPerSecond;
                    
                    // Give points
                    data.Points += config.PointsPerSecond;
                    SaveData();
                    
                    // Show floating text
                    Effect.server.Run("assets/prefabs/missions/portal/proximity_portal/effects/range_check.prefab", player.transform.position, Vector3.zero);
                    
                    // Random message every 10 seconds
                    if (data.Points % (config.PointsPerSecond * 10) == 0)
                    {
                        SendReply(player, $"<color=yellow>🏆 Radiation survival: {data.Points} points earned!</color>");
                    }
                }
            }
        }
        
        private bool IsPlayerInZone(BasePlayer player)
        {
            float distance = Vector3.Distance(player.transform.position, config.ZoneCenter);
            return distance <= config.ZoneRadius;
        }
        
        private void StartRadiationTimer(BasePlayer player)
        {
            if (radiationTimers.ContainsKey(player.userID))
            {
                radiationTimers[player.userID]?.Destroy();
                radiationTimers.Remove(player.userID);
            }
            
            // Check every 5 seconds for lethal radiation
            radiationTimers[player.userID] = timer.Repeat(5f, 0, () =>
            {
                if (player == null || !player.IsConnected || player.IsDead())
                {
                    StopRadiationTimer(player);
                    return;
                }
                
                var data = playerData[player.userID];
                if (data != null && data.IsInZone && player.metabolism.radiation_poison.value >= 400)
                {
                    SendReply(player, $"<color=red>💀 You died from radiation poisoning! Lost 50% of your zone points.</color>");
                    data.Points = Math.Max(0, (int)(data.Points * 0.5f));
                    SaveData();
                }
            });
        }
        
        private void StopRadiationTimer(BasePlayer player)
        {
            if (radiationTimers.ContainsKey(player.userID))
            {
                radiationTimers[player.userID]?.Destroy();
                radiationTimers.Remove(player.userID);
            }
        }
        
        private void CreateMapMarker()
        {
            if (markerObject != null)
                UnityEngine.Object.Destroy(markerObject);
                
            markerObject = new GameObject(config.ZoneMarkerName);
            var marker = markerObject.AddComponent<MapMarkerGenericRadius>();
            marker.radius = config.ZoneRadius / 2f;
            marker.color1 = new Color(1f, 0f, 0f, 0.7f); // Red
            marker.color2 = new Color(1f, 0.5f, 0f, 0.5f); // Orange
            marker.alpha = 0.8f;
            marker.ServerInit();
            marker.transform.position = config.ZoneCenter;
            marker.SendUpdate();
            
            Puts($"Radiation zone marker created at {config.ZoneCenter} with radius {config.ZoneRadius}");
        }
        #endregion

        #region Commands
        [ChatCommand("zone")]
        private void cmdZone(BasePlayer player, string command, string[] args)
        {
            if (args.Length == 0)
            {
                SendReply(player, "<color=yellow>=== Radiation Zone ===</color>");
                SendReply(player, "/zone info - Show zone info and your points");
                SendReply(player, "/zone rewards - Show available rewards");
                SendReply(player, "/zone buy <id> - Buy reward by ID");
                return;
            }
            
            switch (args[0].ToLower())
            {
                case "info":
                    ShowInfo(player);
                    break;
                case "rewards":
                    ShowRewards(player);
                    break;
                case "buy":
                    if (args.Length > 1 && int.TryParse(args[1], out int id))
                    {
                        BuyReward(player, id);
                    }
                    else
                    {
                        SendReply(player, "Usage: /zone buy <reward_id>");
                    }
                    break;
                default:
                    SendReply(player, "Unknown command.Use /zone");
                    break;
            }
        }
        
        private void ShowInfo(BasePlayer player)
        {
            var data = playerData.ContainsKey(player.userID) ? playerData[player.userID] : new PlayerZoneData();
            bool inZone = IsPlayerInZone(player);
            
            SendReply(player, "<color=yellow>=== Zone Info ===</color>");
            SendReply(player, $"📍 Center: {config.ZoneCenter}");
            SendReply(player, $"📏 Radius: {config.ZoneRadius}m");
            SendReply(player, $"☢️ Radiation/sec: {config.RadiationPerSecond}");
            SendReply(player, $"⭐ Points/sec: {config.PointsPerSecond}");
            SendReply(player, $"💰 Your points: {data.Points}");
            SendReply(player, $"🚩 Currently in zone: {(inZone ? "<color=red>YES</color>" : "<color=green>NO</color>")}");
        }
        
        private void ShowRewards(BasePlayer player)
        {
            SendReply(player, "<color=yellow>=== Available Rewards ===</color>");
            for (int i = 0; i < config.Rewards.Count; i++)
            {
                var reward = config.Rewards[i];
                SendReply(player, $"<color=cyan>{i + 1}</color>.{reward.DisplayName} - <color=orange>{reward.PointsCost} points</color>");
            }
        }
        
        private void BuyReward(BasePlayer player, int rewardId)
        {
            if (rewardId < 1 || rewardId > config.Rewards.Count)
            {
                SendReply(player, "Invalid reward ID!");
                return;
            }
            
            var reward = config.Rewards[rewardId - 1];
            var data = playerData.ContainsKey(player.userID) ? playerData[player.userID] : new PlayerZoneData();
            
            if (data.Points < reward.PointsCost)
            {
                SendReply(player, $"<color=red>Not enough points! You have {data.Points}, need {reward.PointsCost}</color>");
                return;
            }
            
            // Give item
            ItemDefinition itemDef = ItemManager.FindItemDefinition(reward.ShortName);
            if (itemDef == null)
            {
                PrintError($"Item '{reward.ShortName}' not found!");
                SendReply(player, "Error: item not found, contact admin");
                return;
            }
            
            Item item = ItemManager.Create(itemDef, reward.Amount);
            if (item != null && player.inventory.GiveItem(item))
            {
                data.Points -= reward.PointsCost;
                SaveData();
                SendReply(player, $"<color=green>✅ You bought {reward.DisplayName} for {reward.PointsCost} points! Remaining: {data.Points}</color>");
                
                // Visual effect
                Effect.server.Run("assets/prefabs/locks/keylock/effects/lock.code.updated.prefab", player.transform.position, Vector3.zero);
            }
            else
            {
                SendReply(player, "Failed to give item.Inventory full?");
            }
        }
        
        [ConsoleCommand("radiationzone.setcenter")]
        private void cmdSetCenter(ConsoleSystem.Arg args)
        {
            if (args.Connection != null && !permission.UserHasPermission(args.Connection.UserId.ToString(), "radiationzone.admin"))
            {
                args.ReplyWith("No permission");
                return;
            }
            
            if (args.Args == null || args.Args.Length < 3)
            {
                args.ReplyWith("Usage: radiationzone.setcenter <x> <z> (y will be auto-detected)");
                return;
            }
            
            float x = Convert.ToSingle(args.Args[0]);
            float z = Convert.ToSingle(args.Args[1]);
            float y = TerrainMeta.HeightMap.GetHeight(new Vector3(x, 0, z));
            
            config.ZoneCenter = new Vector3(x, y, z);
            SaveConfig();
            
            if (config.ShowZoneOnMap)
            {
                CreateMapMarker();
            }
            
            args.ReplyWith($"Radiation zone center set to {config.ZoneCenter} with radius {config.ZoneRadius}");
            Puts($"Radiation zone center updated to {config.ZoneCenter}");
        }
        
        [ConsoleCommand("radiationzone.radius")]
        private void cmdSetRadius(ConsoleSystem.Arg args)
        {
            if (args.Connection != null && !permission.UserHasPermission(args.Connection.UserId.ToString(), "radiationzone.admin"))
            {
                args.ReplyWith("No permission");
                return;
            }
            
            if (args.Args == null || args.Args.Length < 1)
            {
                args.ReplyWith("Usage: radiationzone.radius <radius>");
                return;
            }
            
            config.ZoneRadius = Convert.ToSingle(args.Args[0]);
            SaveConfig();
            
            if (config.ShowZoneOnMap)
            {
                CreateMapMarker();
            }
            
            args.ReplyWith($"Radiation zone radius set to {config.ZoneRadius}");
        }
        
        [ConsoleCommand("radiationzone.givepoints")]
        private void cmdGivePoints(ConsoleSystem.Arg args)
        {
            if (args.Connection != null && !permission.UserHasPermission(args.Connection.UserId.ToString(), "radiationzone.admin"))
            {
                args.ReplyWith("No permission");
                return;
            }
            
            if (args.Args == null || args.Args.Length < 2)
            {
                args.ReplyWith("Usage: radiationzone.givepoints <steamID> <amount>");
                return;
            }
            
            ulong steamId = Convert.ToUInt64(args.Args[0]);
            int amount = Convert.ToInt32(args.Args[1]);
            
            if (!playerData.ContainsKey(steamId))
            {
                playerData[steamId] = new PlayerZoneData();
            }
            
            playerData[steamId].Points += amount;
            SaveData();
            
            args.ReplyWith($"Gave {amount} points to {steamId}");
        }
        #endregion
    }
}

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