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

FREE MiniDeath : 1.0.0 1.0.0

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

namespace Oxide.Plugins
{
    [Info("MiniGun Rockets", "handcaster", "1.0.0")]
    [Description("Adds a MiniGun weapon that fires high velocity rockets")]
    public class MiniDeath : RustPlugin
    {
        private List<ulong> ActiveMiniDeaths = new List<ulong>();
        private ulong miniDeathSkinId = 0;
        private List<ItemId> pendingMiniDeaths = new List<ItemId>(); // Track items waiting for entity spawn
        
        #region Configuration
        private Configuration config;

        public class Configuration
        {
            public string MiniDeathSkinId = "0"; // Default skin
            public string MiniDeathDisplayName = "Mini Death";
            public int MaxAmmoCapacity = 300;
            public string AmmoType = "ammo.rocket.hv";
            public float ProjectileSpeed = 300f; // Speed of the rockets adjusted from 200f to 300f
            public float DamageMultiplier = 8.0f; // Octuple damage
        }

        protected override void LoadDefaultConfig()
        {
            config = new Configuration();
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            config = Config.ReadObject<Configuration>();
            
            // Parse the skin ID once when config loads
            if (!ulong.TryParse(config.MiniDeathSkinId, out miniDeathSkinId))
            {
                PrintError($"Invalid skin ID: {config.MiniDeathSkinId}. Using default.");
                miniDeathSkinId = 0;
            }
            
            PrintWarning($"MiniDeath skin ID set to: {miniDeathSkinId}");
        }

        protected override void SaveConfig()
        {
            Config.WriteObject(config);
        }
        #endregion

        #region Hooks
        void Init()
        {
            permission.RegisterPermission("minideath.give", this);
        }

        void OnServerInitialized()
        {
            PrintWarning("Mini Death plugin loaded! Use /givemd to get one.");
        }

        // Hook when weapon entities are spawned and modify MiniDeath weapons
        void OnEntitySpawned(BaseProjectile weapon)
        {
            if (weapon == null) return;
            
            var item = weapon.GetItem();
            if (item != null && IsMiniDeath(item))
            {
                // This is a MiniDeath weapon being spawned, modify it now
                weapon.primaryMagazine.capacity = config.MaxAmmoCapacity;
                weapon.primaryMagazine.contents = config.MaxAmmoCapacity;
                
                var rifleAmmoDefinition = ItemManager.FindItemDefinition("ammo.rifle");
                if (rifleAmmoDefinition != null)
                {
                    weapon.primaryMagazine.ammoType = rifleAmmoDefinition;
                }
                
                weapon.SendNetworkUpdateImmediate();
                
                // Force another update to ensure it sticks
                NextTick(() => {
                    if (weapon != null && !weapon.IsDestroyed)
                    {
                        weapon.primaryMagazine.capacity = config.MaxAmmoCapacity;
                        weapon.primaryMagazine.contents = config.MaxAmmoCapacity;
                        weapon.SendNetworkUpdateImmediate();
                    }
                });
            }
            // Also check if this is a pending MiniDeath by item ID
            else if (item != null && pendingMiniDeaths.Contains(item.uid))
            {
                weapon.primaryMagazine.capacity = config.MaxAmmoCapacity;
                weapon.primaryMagazine.contents = config.MaxAmmoCapacity;
                
                var rifleAmmoDefinition = ItemManager.FindItemDefinition("ammo.rifle");
                if (rifleAmmoDefinition != null)
                {
                    weapon.primaryMagazine.ammoType = rifleAmmoDefinition;
                }
                
                weapon.SendNetworkUpdateImmediate();
                pendingMiniDeaths.Remove(item.uid);
                
                // Force another update to ensure it sticks
                NextTick(() => {
                    if (weapon != null && !weapon.IsDestroyed)
                    {
                        weapon.primaryMagazine.capacity = config.MaxAmmoCapacity;
                        weapon.primaryMagazine.contents = config.MaxAmmoCapacity;
                        weapon.SendNetworkUpdateImmediate();
                    }
                });
            }
        }

        // Hook for when rockets spawn to modify their damage
        void OnEntitySpawned(TimedExplosive rocket)
        {
            if (rocket == null || rocket.ShortPrefabName != "rocket_hv") return;
            
            // Check if this rocket was fired from a MiniDeath
            if (rocket.creatorEntity is BasePlayer player)
            {
                var activeItem = player.GetActiveItem();
                if (activeItem != null && IsMiniDeath(activeItem))
                {
                    // This rocket came from a MiniDeath, modify its damage
                    var explosive = rocket.GetComponent<TimedExplosive>();
                    if (explosive != null)
                    {
                        explosive.explosionRadius *= config.DamageMultiplier;
                        explosive.timerAmountMax *= config.DamageMultiplier;
                        explosive.timerAmountMin *= config.DamageMultiplier;
                    }
                    
                    // Also modify the damage list
                    if (rocket.damageTypes != null)
                    {
                        for (int i = 0; i < rocket.damageTypes.Count; i++)
                        {
                            rocket.damageTypes[i].amount *= config.DamageMultiplier;
                        }
                    }
                }
            }
        }

        // Use 5.56 ammo detection since that's what the minigun uses
        void OnWeaponFired(BaseProjectile weapon, BasePlayer player, ItemModProjectile ammo, ProtoBuf.ProjectileShoot projectiles)
        {
            if (player == null) return;
            
            if (IsMiniDeath(weapon.GetItem()) && ammo.ammoType == Rust.AmmoTypes.RIFLE_556MM)
            {
                string rocket = "assets/prefabs/ammo/rocket/rocket_hv.prefab";
                FireRockets(player, rocket);
            }
        }

        // Initialize the weapon properly when equipped
        void OnPlayerActiveItemChanged(BasePlayer player, Item oldItem, Item newItem)
        {
            if (newItem != null && IsMiniDeath(newItem))
            {
                var weapon = newItem.GetHeldEntity() as BaseProjectile;
                if (weapon != null)
                {
                    // Initialize with proper ammo type to enable reload animations
                    InitializeMiniDeathAmmo(weapon);
                    
                    // Force the capacity after equipping (backup)
                    weapon.primaryMagazine.capacity = config.MaxAmmoCapacity;
                    weapon.SendNetworkUpdateImmediate();
                    
                    // Double check with delay
                    timer.Once(0.1f, () => {
                        if (weapon != null && !weapon.IsDestroyed)
                        {
                            weapon.primaryMagazine.capacity = config.MaxAmmoCapacity;
                            weapon.SendNetworkUpdateImmediate();
                        }
                    });
                }
            }
        }

        // Intercept unload to give back HV rockets instead of 5.56 ammo
        void OnAmmoUnload(BaseProjectile weapon, Item item, BasePlayer player)
        {
            if (IsMiniDeath(weapon.GetItem()))
            {
                timer.Once(0.1f, () => {
                    // Remove any 5.56 ammo that was unloaded
                    var rifleAmmo = player.inventory.FindItemByItemID(-1211166256); // 5.56 ammo ID
                    if (rifleAmmo != null)
                    {
                        int ammoCount = rifleAmmo.amount;
                        rifleAmmo.Remove();
                        
                        // Give HV rockets instead
                        var hvRockets = ItemManager.Create(ItemManager.FindItemDefinition(config.AmmoType), ammoCount);
                        if (!hvRockets.MoveToContainer(player.inventory.containerMain))
                        {
                            hvRockets.Drop(player.transform.position, Vector3.zero);
                        }
                        player.ChatMessage($"Unloaded {ammoCount} HV rockets from Mini Death");
                    }
                });
            }
        }

        void OnPlayerInput(BasePlayer player, InputState input)
        {
            if (player.GetActiveItem() != null && IsMiniDeath(player.GetActiveItem()))
            {
                if (input.WasJustPressed(BUTTON.RELOAD))
                {
                    var weapon = player.GetActiveItem().GetHeldEntity() as BaseProjectile;
                    if (weapon != null)
                    {
                        LoadMiniDeathAmmo(weapon, player);
                    }
                }
            }
        }
        #endregion

        #region Core Methods
        private bool IsMiniDeath(Item item)
        {
            if (item?.info?.shortname != "minigun") return false;
            return item.name == config.MiniDeathDisplayName;
        }

        private void InitializeMiniDeathAmmo(BaseProjectile weapon)
        {
            if (weapon == null) return;
            
            // Set the ammo type to 5.56 definition to enable reload animations
            var rifleAmmoDefinition = ItemManager.FindItemDefinition("ammo.rifle");
            if (rifleAmmoDefinition != null)
            {
                weapon.primaryMagazine.ammoType = rifleAmmoDefinition;
                weapon.SendNetworkUpdateImmediate();
            }
        }

        public void FireRockets(BasePlayer player, string rocketPrefab)
        {
            if (player == null) return;
            
            var rocket = GameManager.server.CreateEntity(rocketPrefab, player.eyes.position, new Quaternion());
            if (rocket != null)
            {
                rocket.creatorEntity = player;
                rocket.SendMessage("InitializeVelocity", player.eyes.HeadForward() * config.ProjectileSpeed);
                rocket.OwnerID = player.userID;
                rocket.Spawn();
                rocket.ClientRPC(null, "RPCFire");
                
                Interface.CallHook("OnRocketLaunched", player, rocket);
            }
        }

        private void LoadMiniDeathAmmo(BaseProjectile weapon, BasePlayer player)
        {
            try
            {
                var item = weapon.GetItem();
                if (!IsMiniDeath(item)) return;

                Item hvRocketItem = null;
                
                // Look for HV rockets in inventory
                foreach (var invItem in player.inventory.containerMain.itemList)
                {
                    if (invItem.info.shortname == config.AmmoType)
                    {
                        hvRocketItem = invItem;
                        break;
                    }
                }
                
                if (hvRocketItem == null)
                {
                    foreach (var invItem in player.inventory.containerBelt.itemList)
                    {
                        if (invItem.info.shortname == config.AmmoType)
                        {
                            hvRocketItem = invItem;
                            break;
                        }
                    }
                }

                if (hvRocketItem != null)
                {
                    int currentAmmo = weapon.primaryMagazine.contents;
                    int maxCapacity = weapon.primaryMagazine.capacity;
                    int neededAmmo = maxCapacity - currentAmmo;
                    
                    if (neededAmmo > 0)
                    {
                        int ammoToTake = Mathf.Min(neededAmmo, hvRocketItem.amount);
                        
                        // Remove HV rockets from inventory
                        hvRocketItem.UseItem(ammoToTake);
                        
                        // Add some 5.56 ammo temporarily to trigger the reload animation
                        var tempRifleAmmo = ItemManager.Create(ItemManager.FindItemDefinition("ammo.rifle"), 1);
                        if (tempRifleAmmo != null)
                        {
                            // Put 5.56 ammo in player inventory temporarily
                            tempRifleAmmo.MoveToContainer(player.inventory.containerMain);
                            
                            // Set magazine to empty and let the game naturally reload
                            weapon.primaryMagazine.contents = 0;
                            
                            // Add delay to allow reload animation, then fix the ammo
                            timer.Once(1.0f, () => {
                                if (weapon != null && !weapon.IsDestroyed)
                                {
                                    // Remove the temporary 5.56 ammo
                                    var foundRifleAmmo = player.inventory.FindItemByItemID(1712070256); // 5.56 ammo ID
                                    if (foundRifleAmmo != null)
                                    {
                                        foundRifleAmmo.Remove();
                                    }
                                    
                                    // Set correct ammo count
                                    weapon.primaryMagazine.contents = currentAmmo + ammoToTake;
                                    weapon.SendNetworkUpdateImmediate();
                                }
                            });
                        }
                        else
                        {
                            // Fallback if temp ammo fails - just add the ammo directly
                            weapon.primaryMagazine.contents += ammoToTake;
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                PrintError($"Error in LoadMiniDeathAmmo: {ex.Message}");
            }
        }
        #endregion

        #region Commands
        [ChatCommand("givemd")]
        private void GiveMiniDeathCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "minideath.give"))
            {
                player.ChatMessage("You don't have permission to use this command.");
                return;
            }

            // Create Minigun
            var minigunItem = ItemManager.CreateByName("minigun", 1);
            if (minigunItem != null)
            {
                // Set name to identify it as MiniDeath
                minigunItem.name = config.MiniDeathDisplayName;
                
                // Add to pending list so OnEntitySpawned can catch it
                pendingMiniDeaths.Add(minigunItem.uid);

                // Remove attachment slots
                if (minigunItem.contents != null)
                {
                    for (int i = minigunItem.contents.itemList.Count - 1; i >= 0; i--)
                    {
                        var attachment = minigunItem.contents.itemList[i];
                        attachment.Remove();
                    }
                    minigunItem.contents.capacity = 0;
                }

                minigunItem.MarkDirty();
                
                // Give it to the player - this will trigger entity spawn
                player.GiveItem(minigunItem);
                
                // Force check the weapon after a short delay
                timer.Once(0.2f, () => {
                    var activeItem = player.GetActiveItem();
                    if (activeItem != null && IsMiniDeath(activeItem))
                    {
                        var weapon = activeItem.GetHeldEntity() as BaseProjectile;
                        if (weapon != null)
                        {
                            weapon.primaryMagazine.capacity = config.MaxAmmoCapacity;
                            weapon.primaryMagazine.contents = config.MaxAmmoCapacity;
                            weapon.SendNetworkUpdateImmediate();
                        }
                    }
                });
            }
        }

        [ChatCommand("mdskin")]
        private void SetMiniDeathSkinCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, "minideath.give"))
            {
                player.ChatMessage("You don't have permission to use this command.");
                return;
            }

            if (args.Length == 0)
            {
                player.ChatMessage("Usage: /mdskin <skinid> - Apply skin to MiniDeath in your hands");
                return;
            }

            if (!ulong.TryParse(args[0], out ulong skinId))
            {
                player.ChatMessage("Invalid skin ID. Please provide a numeric skin ID.");
                return;
            }

            var activeItem = player.GetActiveItem();
            if (activeItem == null || !IsMiniDeath(activeItem))
            {
                player.ChatMessage("You must be holding a MiniDeath to apply a skin.");
                return;
            }

            activeItem.skin = skinId;
            activeItem.MarkDirty();
            
            player.ChatMessage($"Applied skin ID {skinId} to your MiniDeath!");
        }
        #endregion
    }
}

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