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

FREE AirDropEvent : 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;
using Random = System.Random;

namespace Oxide.Plugins
{
    [Info("Air Drop Event", "0killrest", "1.0.0")]
    [Description("PUBG-style airdrop events with planes, smoke, and loot")]
    internal class AirDropEvent : RustPlugin
    {
        #region Configuration
        private static ConfigData config;
        
        private class ConfigData
        {
            public bool Enabled { get; set; } = true;
            public float DropIntervalMinutes { get; set; } = 10f;
            public int DropsPerEvent { get; set; } = 1;
            public bool AnnounceDrop { get; set; } = true;
            public bool PlayPlaneSound { get; set; } = true;
            public bool ShowMapMarker { get; set; } = true;
            public bool DropSmokeEffect { get; set; } = true;
            public float PlaneFlyHeight { get; set; } = 300f;
            public float PlaneFlySpeed { get; set; } = 80f;
            public int LootAmountMin { get; set; } = 5;
            public int LootAmountMax { get; set; } = 12;
            public List<LootItem> LootTable { get; set; }
            
            public ConfigData()
            {
                LootTable = new List<LootItem>
                {
                    // Оружие
                    new LootItem { ShortName = "rifle.ak", MinAmount = 1, MaxAmount = 1, Chance = 15, DisplayName = "AK-47" },
                    new LootItem { ShortName = "rifle.lr300", MinAmount = 1, MaxAmount = 1, Chance = 12, DisplayName = "LR-300" },
                    new LootItem { ShortName = "smg.mp5", MinAmount = 1, MaxAmount = 1, Chance = 15, DisplayName = "MP5" },
                    new LootItem { ShortName = "pistol.m92", MinAmount = 1, MaxAmount = 1, Chance = 20, DisplayName = "M92" },
                    new LootItem { ShortName = "shotgun.spas12", MinAmount = 1, MaxAmount = 1, Chance = 12, DisplayName = "SPAS-12" },
                    new LootItem { ShortName = "bolt.rifle", MinAmount = 1, MaxAmount = 1, Chance = 8, DisplayName = "Bolt Rifle" },
                    
                    // Патроны
                    new LootItem { ShortName = "ammo.rifle", MinAmount = 30, MaxAmount = 60, Chance = 80, DisplayName = "Rifle Ammo" },
                    new LootItem { ShortName = "ammo.pistol", MinAmount = 30, MaxAmount = 60, Chance = 70, DisplayName = "Pistol Ammo" },
                    new LootItem { ShortName = "ammo.shotgun", MinAmount = 12, MaxAmount = 24, Chance = 60, DisplayName = "Shotgun Shells" },
                    
                    // Аптечки и хилки
                    new LootItem { ShortName = "large.medkit", MinAmount = 1, MaxAmount = 3, Chance = 90, DisplayName = "Medkit" },
                    new LootItem { ShortName = "syringe.medical", MinAmount = 2, MaxAmount = 5, Chance = 85, DisplayName = "Syringe" },
                    new LootItem { ShortName = "bandage", MinAmount = 5, MaxAmount = 10, Chance = 95, DisplayName = "Bandage" },
                    
                    // Броня
                    new LootItem { ShortName = "metal.plate.torso", MinAmount = 1, MaxAmount = 1, Chance = 25, DisplayName = "Metal Chestplate" },
                    new LootItem { ShortName = "metal.plate.pants", MinAmount = 1, MaxAmount = 1, Chance = 25, DisplayName = "Metal Pants" },
                    new LootItem { ShortName = "coffeecan.helmet", MinAmount = 1, MaxAmount = 1, Chance = 30, DisplayName = "Coffee Can Helmet" },
                    
                    // Еда
                    new LootItem { ShortName = "apple", MinAmount = 3, MaxAmount = 8, Chance = 85, DisplayName = "Apple" },
                    new LootItem { ShortName = "can.beans", MinAmount = 2, MaxAmount = 5, Chance = 70, DisplayName = "Canned Beans" },
                    new LootItem { ShortName = "chocolate", MinAmount = 2, MaxAmount = 4, Chance = 65, DisplayName = "Chocolate Bar" },
                    
                    // Гранаты и взрывчатка
                    new LootItem { ShortName = "grenade.f1", MinAmount = 1, MaxAmount = 3, Chance = 40, DisplayName = "F1 Grenade" },
                    new LootItem { ShortName = "explosive.timed", MinAmount = 1, MaxAmount = 2, Chance = 15, DisplayName = "C4" },
                    new LootItem { ShortName = "ammo.rocket.basic", MinAmount = 2, MaxAmount = 5, Chance = 10, DisplayName = "Rockets" },
                    
                    // Ресурсы
                    new LootItem { ShortName = "scrap", MinAmount = 50, MaxAmount = 200, Chance = 100, DisplayName = "Scrap" },
                    new LootItem { ShortName = "metal.refined", MinAmount = 100, MaxAmount = 300, Chance = 75, DisplayName = "Metal Fragments" },
                    new LootItem { ShortName = "sulfur", MinAmount = 100, MaxAmount = 250, Chance = 65, DisplayName = "Sulfur" }
                };
            }
        }
        
        public class LootItem
        {
            public string ShortName { get; set; }
            public int MinAmount { get; set; }
            public int MaxAmount { get; set; }
            public int Chance { 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/AirDropEvent.json");
            SaveConfig();
        }
        
        protected override void SaveConfig() => Config.WriteObject(config);
        #endregion

        #region Data
        private Timer dropTimer;
        private Random random = new Random();
        private List<DropCrate> activeDrops = new List<DropCrate>();
        
        private class DropCrate
        {
            public SupplyDrop Crate { get; set; }
            public Vector3 Position { get; set; }
            public float LandTime { get; set; }
            public bool IsLanded { get; set; }
        }
        #endregion

        #region Hooks
        private void Init()
        {
            permission.RegisterPermission("airdropevent.admin", this);
        }
        
        private void OnServerInitialized()
        {
            if (config.Enabled)
            {
                StartDropTimer();
            }
        }
        
        private void Unload()
        {
            dropTimer?.Destroy();
        }
        
        private void StartDropTimer()
        {
            if (dropTimer != null)
            {
                dropTimer.Destroy();
            }
            
            dropTimer = timer.Repeat(config.DropIntervalMinutes * 60f, 0, () =>
            {
                ExecuteAirDrop();
            });
            
            Puts($"AirDropEvent enabled: drops every {config.DropIntervalMinutes} minutes");
        }
        
        private void ExecuteAirDrop()
        {
            if (!config.Enabled) return;
            
            for (int i = 0; i < config.DropsPerEvent; i++)
            {
                SpawnAirDrop();
            }
        }
        
        private void SpawnAirDrop()
        {
            // Get random position on map
            Vector3 dropPosition = GetRandomDropPosition();
            
            // Play plane sound effect (server-wide)
            if (config.PlayPlaneSound)
            {
                Effect.server.Run("assets/prefabs/npc/cargo plane/effects/plane-flyby.prefab", dropPosition, Vector3.zero);
            }
            
            // Announce to all players
            if (config.AnnounceDrop)
            {
                string announceMessage = $"<color=orange>✈️ AIRDROP INCOMING!</color> A supply drop is falling at <color=yellow>{GetGridPosition(dropPosition)}</color>!";
                Server.Broadcast(announceMessage);
                PrintToChat(announceMessage);
            }
            
            // Spawn the supply drop
            SupplyDrop supplyDrop = GameManager.server.CreateEntity("assets/prefabs/misc/supply drop/supply_drop.prefab", dropPosition) as SupplyDrop;
            if (supplyDrop == null)
            {
                PrintError("Failed to create supply drop!");
                return;
            }
            
            // Configure the drop
            supplyDrop.Invoke(new Action(supplyDrop.InitSupplyDrop), 0.1f);
            supplyDrop.Spawn();
            
            // Add smoke effect
            if (config.DropSmokeEffect)
            {
                AddSmokeEffect(dropPosition);
            }
            
            // Add map marker
            if (config.ShowMapMarker)
            {
                AddMapMarker(dropPosition);
            }
            
            // Customize loot
            CustomizeLoot(supplyDrop);
            
            // Track active drop
            activeDrops.Add(new DropCrate
            {
                Crate = supplyDrop,
                Position = dropPosition,
                LandTime = Time.realtimeSinceStartup + 15f,
                IsLanded = false
            });
            
            Puts($"Airdrop spawned at {dropPosition}");
            
            // Schedule cleanup for landed drops (10 minutes)
            timer.Once(600f, () =>
            {
                if (supplyDrop != null && !supplyDrop.IsDestroyed)
                {
                    supplyDrop.Kill();
                    activeDrops.RemoveAll(d => d.Crate == supplyDrop);
                }
            });
        }
        
        private Vector3 GetRandomDropPosition()
        {
            // Try up to 10 times to find a valid position (not in water, not too close to edge)
            for (int i = 0; i < 10; i++)
            {
                float x = (float)random.NextDouble() * (TerrainMeta.Size.x - 200f) + 100f;
                float z = (float)random.NextDouble() * (TerrainMeta.Size.z - 200f) + 100f;
                float y = TerrainMeta.HeightMap.GetHeight(new Vector3(x, 0, z)) + 5f;
                
                Vector3 pos = new Vector3(x, y, z);
                
                // Check if not in water
                if (!IsInWater(pos))
                {
                    return pos;
                }
            }
            
            // Fallback to center of map
            float centerX = TerrainMeta.Size.x / 2f;
            float centerZ = TerrainMeta.Size.z / 2f;
            float centerY = TerrainMeta.HeightMap.GetHeight(new Vector3(centerX, 0, centerZ)) + 5f;
            return new Vector3(centerX, centerY, centerZ);
        }
        
        private bool IsInWater(Vector3 position)
        {
            // Simple water check
            return position.y < TerrainMeta.WaterMap.GetHeight(position);
        }
        
        private string GetGridPosition(Vector3 position)
        {
            // Convert world position to grid reference (e.g., "G5")
            int gridSize = 10;
            float mapSize = TerrainMeta.Size.x;
            float cellSize = mapSize / gridSize;
            
            char xChar = (char)('A' + Mathf.FloorToInt(position.x / cellSize));
            int zNum = Mathf.FloorToInt(position.z / cellSize) + 1;
            
            return $"{xChar}{zNum}";
        }
        
        private void AddSmokeEffect(Vector3 position)
        {
            // Add smoke grenade effect at drop location
            Effect.server.Run("assets/prefabs/npc/sam_site_turret/effects/sam_site_rocket_smoke.prefab", position, Vector3.zero);
        }
        
        private void AddMapMarker(Vector3 position)
        {
            // Create a map marker for all players
            foreach (var player in BasePlayer.activePlayerList)
            {
                player.SendConsoleCommand("createmarker", 
                    $"airdrop_{position}", 
                    "🎁 Air Drop", 
                    "red", 
                    position);
            }
            
            // Auto-remove marker after 5 minutes
            timer.Once(300f, () =>
            {
                foreach (var player in BasePlayer.activePlayerList)
                {
                    player.SendConsoleCommand("removemarker", $"airdrop_{position}");
                }
            });
        }
        
        private void CustomizeLoot(SupplyDrop supplyDrop)
        {
            if (supplyDrop == null || supplyDrop.inventory == null) return;
            
            // Clear default loot
            supplyDrop.inventory.Clear();
            
            // Determine how many items to add
            int itemCount = random.Next(config.LootAmountMin, config.LootAmountMax + 1);
            
            // Filter loot table by chance
            List<LootItem> availableLoot = new List<LootItem>();
            foreach (var lootItem in config.LootTable)
            {
                if (random.Next(100) < lootItem.Chance)
                {
                    availableLoot.Add(lootItem);
                }
            }
            
            // Shuffle and pick items
            availableLoot = availableLoot.OrderBy(x => random.Next()).ToList();
            
            for (int i = 0; i < Math.Min(itemCount, availableLoot.Count); i++)
            {
                var lootItem = availableLoot[i];
                int amount = random.Next(lootItem.MinAmount, lootItem.MaxAmount + 1);
                
                ItemDefinition itemDef = ItemManager.FindItemDefinition(lootItem.ShortName);
                if (itemDef != null)
                {
                    Item item = ItemManager.Create(itemDef, amount);
                    if (item != null && !supplyDrop.inventory.IsFull())
                    {
                        supplyDrop.inventory.Insert(item);
                    }
                }
            }
            
            // Always add some scrap if not enough items
            if (supplyDrop.inventory.itemList.Count < 3)
            {
                Item scrap = ItemManager.Create(ItemManager.FindItemDefinition("scrap"), random.Next(50, 150));
                if (scrap != null)
                {
                    supplyDrop.inventory.Insert(scrap);
                }
            }
            
            Puts($"Airdrop loot populated with {supplyDrop.inventory.itemList.Count} items");
        }
        
        private void OnLootEntity(BasePlayer player, SupplyDrop entity)
        {
            // Check if this is our drop
            var drop = activeDrops.FirstOrDefault(d => d.Crate == entity);
            if (drop == null) return;
            
            // Announce who looted
            if (drop.IsLanded && config.AnnounceDrop)
            {
                string lootMessage = $"<color=green>🎁 {player.displayName} looted the airdrop at {GetGridPosition(drop.Position)}!</color>";
                Server.Broadcast(lootMessage);
            }
            
            // Remove from active drops
            activeDrops.Remove(drop);
        }
        
        private void OnSupplyDropLanded(SupplyDrop supplyDrop)
        {
            var drop = activeDrops.FirstOrDefault(d => d.Crate == supplyDrop);
            if (drop != null)
            {
                drop.IsLanded = true;
                
                if (config.AnnounceDrop)
                {
                    string landedMessage = $"<color=orange>📦 The airdrop has landed at {GetGridPosition(drop.Position)}! Go get it!</color>";
                    Server.Broadcast(landedMessage);
                }
                
                // Add smoke effect on landing
                Effect.server.Run("assets/prefabs/npc/sam_site_turret/effects/sam_site_rocket_smoke.prefab", drop.Position, Vector3.zero);
            }
        }
        #endregion

        #region Commands
        [ChatCommand("airdrop")]
        private void cmdAirdrop(BasePlayer player, string command, string[] args)
        {
            if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, "airdropevent.admin"))
            {
                SendReply(player, "You don't have permission to use this command.");
                return;
            }
            
            if (args.Length > 0 && args[0].ToLower() == "spawn")
            {
                SpawnAirDrop();
                SendReply(player, "Airdrop spawned!");
            }
            else
            {
                float nextDrop = dropTimer != null ? config.DropIntervalMinutes : 0;
                SendReply(player, $"<color=yellow>=== AirDrop Info ===</color>");
                SendReply(player, $"Next drop in: {nextDrop} minutes");
                SendReply(player, $"Active drops: {activeDrops.Count}");
                SendReply(player, $"Type <color=green>/airdrop spawn</color> to force a drop");
            }
        }
        
        [ConsoleCommand("airdrop.spawn")]
        private void cmdConsoleSpawn(ConsoleSystem.Arg args)
        {
            if (args.Connection != null && !permission.UserHasPermission(args.Connection.UserId.ToString(), "airdropevent.admin"))
            {
                args.ReplyWith("No permission");
                return;
            }
            
            SpawnAirDrop();
            args.ReplyWith("Airdrop spawned");
        }
        
        [ConsoleCommand("airdrop.reload")]
        private void cmdConsoleReload(ConsoleSystem.Arg args)
        {
            if (args.Connection != null && !permission.UserHasPermission(args.Connection.UserId.ToString(), "airdropevent.admin"))
            {
                args.ReplyWith("No permission");
                return;
            }
            
            LoadConfig();
            args.ReplyWith("AirDropEvent reloaded");
        }
        
        [ConsoleCommand("airdrop.status")]
        private void cmdConsoleStatus(ConsoleSystem.Arg args)
        {
            if (args.Connection != null && !permission.UserHasPermission(args.Connection.UserId.ToString(), "airdropevent.admin"))
            {
                args.ReplyWith("No permission");
                return;
            }
            
            args.ReplyWith($"AirDropEvent: {activeDrops.Count} active drops, interval {config.DropIntervalMinutes} min");
        }
        #endregion
    }
}

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