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

FREE OneHitFarm : 1.5.2 1.5.2

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Oxide.Core;
using Oxide.Core.Plugins;
using UnityEngine;
using System.Collections.Generic;
using System;
using Rust;
using System.Linq;

namespace Oxide.Plugins
{
    [Info("One Hit Farm", "rustmods.ru", "1.5.2")]
    [Description("Instantly gather resources from trees and ores with one hit")]
    public class OneHitFarm : RustPlugin
    {
        #region Fields
        private ConfigData configData;
        private const string PERMISSION_USE = "onehitfarm.use";
        private const string PERMISSION_ADMIN = "onehitfarm.admin";
        private readonly DateTime startTime = DateTime.UtcNow;
        private bool isInitialized;
        private bool isLoaded;
        private const float MIN_HEALTH = 0f;
        private const float MAX_GATHER_DISTANCE = 5f;
        #endregion

        #region Configuration
        private class ConfigData
        {
            public bool Enabled { get; set; }
            public bool EnableLogging { get; set; }
            public bool RequirePermission { get; set; }
            public bool RequireTool { get; set; }
            public bool EnablePerformanceLogging { get; set; }
            public float MaxGatherDistance { get; set; }

            // Detaylı toplama ayarları
            public ResourceSettings ResourceSettings { get; set; }

            public ConfigData()
            {
                SetDefaults();
            }

            private void SetDefaults()
            {
                Enabled = true;
                EnableLogging = false;
                RequirePermission = true;
                RequireTool = true;
                EnablePerformanceLogging = false;
                MaxGatherDistance = 5f;

                ResourceSettings = new ResourceSettings
                {
                    // Rock ayarları
                    Rock = new ToolSettings
                    {
                        Enabled = true,
                        GatherMultiplier = 0.1f,
                        MinAmount = 1,
                        MaxMultiplier = 1.0f,
                        GatherAttempts = 2,
                        DamageAmount = 1f,
                        ShowGatherEffects = true
                    },

                    // Normal alet ayarları
                    Tools = new ToolSettings
                    {
                        Enabled = true,
                        GatherMultiplier = 1.0f,
                        MinAmount = 1,
                        MaxMultiplier = 10.0f,
                        GatherAttempts = 1,
                        DamageAmount = 50f,
                        ShowGatherEffects = true
                    },

                    // Kaynak tipi ayarları
                    ResourceTypes = new ResourceTypeSettings
                    {
                        // Ağaç ayarları
                        Tree = new ResourceTypeConfig
                        {
                            Enabled = true,
                            BaseMultiplier = 1.0f,
                            MinAmount = 1,
                            MaxAmount = 1000,
                            EffectPrefab = "assets/bundled/prefabs/fx/hit_mark_wood.prefab",
                            CustomDrops = new List<CustomDrop>()
                        },

                        // Metal ayarları
                        Metal = new ResourceTypeConfig
                        {
                            Enabled = true,
                            BaseMultiplier = 1.0f,
                            MinAmount = 1,
                            MaxAmount = 1000,
                            EffectPrefab = "assets/bundled/prefabs/fx/hit_mark_metal.prefab",
                            CustomDrops = new List<CustomDrop>()
                        },

                        // Sülfür ayarları
                        Sulfur = new ResourceTypeConfig
                        {
                            Enabled = true,
                            BaseMultiplier = 1.0f,
                            MinAmount = 1,
                            MaxAmount = 1000,
                            EffectPrefab = "assets/bundled/prefabs/fx/ore_break.prefab",
                            CustomDrops = new List<CustomDrop>()
                        },

                        // Taş ayarları
                        Stone = new ResourceTypeConfig
                        {
                            Enabled = true,
                            BaseMultiplier = 1.0f,
                            MinAmount = 1,
                            MaxAmount = 1000,
                            EffectPrefab = "assets/bundled/prefabs/fx/hit_mark_stone.prefab",
                            CustomDrops = new List<CustomDrop>()
                        }
                    }
                };
            }
        }

        private class ResourceSettings
        {
            public ToolSettings Rock { get; set; }
            public ToolSettings Tools { get; set; }
            public ResourceTypeSettings ResourceTypes { get; set; }
        }

        private class ToolSettings
        {
            public bool Enabled { get; set; }
            public float GatherMultiplier { get; set; }
            public int MinAmount { get; set; }
            public float MaxMultiplier { get; set; }
            public int GatherAttempts { get; set; }
            public float DamageAmount { get; set; }
            public bool ShowGatherEffects { get; set; }
        }

        private class ResourceTypeSettings
        {
            public ResourceTypeConfig Tree { get; set; }
            public ResourceTypeConfig Metal { get; set; }
            public ResourceTypeConfig Sulfur { get; set; }
            public ResourceTypeConfig Stone { get; set; }
        }

        private class ResourceTypeConfig
        {
            public bool Enabled { get; set; }
            public float BaseMultiplier { get; set; }
            public int MinAmount { get; set; }
            public int MaxAmount { get; set; }
            public string EffectPrefab { get; set; }
            public List<CustomDrop> CustomDrops { get; set; }
        }

        private class CustomDrop
        {
            public string ItemShortName { get; set; }
            public float Chance { get; set; }
            public int MinAmount { get; set; }
            public int MaxAmount { get; set; }
        }

        protected override void LoadDefaultConfig()
        {
            configData = new ConfigData();
            Config.WriteObject(configData, true);
        }

        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                configData = Config.ReadObject<ConfigData>();
                if (configData == null)
                {
                    throw new Exception("Config is null!");
                }
                ValidateConfig();
            }
            catch (Exception ex)
            {
                PrintError($"Configuration error: {ex.Message}");
                LoadDefaultConfig();
            }
        }

        private void ValidateConfig()
        {
            if (configData.ResourceSettings == null)
                configData.ResourceSettings = new ResourceSettings();

            // Rock ayarlarını kontrol et
            if (configData.ResourceSettings.Rock == null)
                configData.ResourceSettings.Rock = new ToolSettings();

            // Tool ayarlarını kontrol et
            if (configData.ResourceSettings.Tools == null)
                configData.ResourceSettings.Tools = new ToolSettings();

            // Resource type ayarlarını kontrol et
            if (configData.ResourceSettings.ResourceTypes == null)
                configData.ResourceSettings.ResourceTypes = new ResourceTypeSettings();

            // Sınırları kontrol et
            configData.MaxGatherDistance = Mathf.Clamp(configData.MaxGatherDistance, 1f, 10f);
            
            ValidateToolSettings(configData.ResourceSettings.Rock);
            ValidateToolSettings(configData.ResourceSettings.Tools);
            ValidateResourceTypeSettings(configData.ResourceSettings.ResourceTypes);

            SaveConfig();
        }

        private void ValidateToolSettings(ToolSettings settings)
        {
            if (settings == null) return;

            settings.GatherMultiplier = Mathf.Clamp(settings.GatherMultiplier, 0.1f, 100f);
            settings.MinAmount = Mathf.Max(1, settings.MinAmount);
            settings.MaxMultiplier = Mathf.Clamp(settings.MaxMultiplier, 0.1f, 100f);
            settings.GatherAttempts = Mathf.Clamp(settings.GatherAttempts, 1, 10);
            settings.DamageAmount = Mathf.Clamp(settings.DamageAmount, 0.1f, 1000f);
        }

        private void ValidateResourceTypeSettings(ResourceTypeSettings settings)
        {
            if (settings == null) return;

            ValidateResourceTypeConfig(settings.Tree);
            ValidateResourceTypeConfig(settings.Metal);
            ValidateResourceTypeConfig(settings.Sulfur);
            ValidateResourceTypeConfig(settings.Stone);
        }

        private void ValidateResourceTypeConfig(ResourceTypeConfig config)
        {
            if (config == null) return;

            config.BaseMultiplier = Mathf.Clamp(config.BaseMultiplier, 0.1f, 100f);
            config.MinAmount = Mathf.Max(1, config.MinAmount);
            config.MaxAmount = Mathf.Max(config.MinAmount, config.MaxAmount);

            if (string.IsNullOrEmpty(config.EffectPrefab))
                config.EffectPrefab = "assets/bundled/prefabs/fx/hit_mark_metal.prefab";

            if (config.CustomDrops == null)
                config.CustomDrops = new List<CustomDrop>();
        }
        #endregion

        #region Localization
        protected override void LoadDefaultMessages()
        {
            // Load language files
            LoadLanguageFile("en");
            LoadLanguageFile("tr");
            LoadLanguageFile("de");
            LoadLanguageFile("fr");
            LoadLanguageFile("ru");
        }

        private void LoadLanguageFile(string code)
        {
            var messages = new Dictionary<string, string>();
            var path = $"lang/{code}.json";

            try
            {
                if (Interface.Oxide.DataFileSystem.ExistsDatafile(path))
                {
                    messages = Interface.Oxide.DataFileSystem.ReadObject<Dictionary<string, string>>(path);
                }
                else
                {
                    messages = GetDefaultMessages(code);
                }

                lang.RegisterMessages(messages, this, code);
            }
            catch (Exception ex)
            {
                PrintError($"Error loading language file {code}: {ex.Message}");
            }
        }

        private Dictionary<string, string> GetDefaultMessages(string code)
        {
            switch (code.ToLower())
            {
                case "tr":
                    return new Dictionary<string, string>
                    {
                        ["NoPermission"] = "Bu komutu kullanma izniniz yok!",
                        ["Usage"] = "Kullanım: /onehitfarm <on|off|status>",
                        ["Enabled"] = "OneHitFarm aktif edildi!",
                        ["Disabled"] = "OneHitFarm devre dışı bırakıldı!",
                        ["Status"] = "OneHitFarm şu anda {0}",
                        ["StatusEnabled"] = "aktif",
                        ["StatusDisabled"] = "devre dışı",
                        ["InvalidArg"] = "Geçersiz argüman! Kullanım: /onehitfarm <on|off|status>",
                        ["ToolUsed"] = "Kullanılan alet: {0}",
                        ["HitTree"] = "{0} bir ağaca vurdu!",
                        ["HitOre"] = "{0} bir madene vurdu!",
                        ["ResourceGathered"] = "{0} kaynak topladı! Miktar: {1}",
                        ["Error"] = "Bir hata oluştu: {0}"
                    };
                case "de":
                    return new Dictionary<string, string>
                    {
                        ["NoPermission"] = "Sie haben keine Berechtigung, diesen Befehl zu verwenden!",
                        ["Usage"] = "Verwendung: /onehitfarm <on|off|status>",
                        ["Enabled"] = "OneHitFarm wurde aktiviert!",
                        ["Disabled"] = "OneHitFarm wurde deaktiviert!",
                        ["Status"] = "OneHitFarm ist derzeit {0}",
                        ["StatusEnabled"] = "aktiviert",
                        ["StatusDisabled"] = "deaktiviert",
                        ["InvalidArg"] = "Ungültiges Argument! Verwendung: /onehitfarm <on|off|status>",
                        ["ToolUsed"] = "Verwendetes Werkzeug: {0}",
                        ["HitTree"] = "{0} hat einen Baum getroffen!",
                        ["HitOre"] = "{0} hat ein Erz getroffen!",
                        ["ResourceGathered"] = "{0} hat Ressourcen gesammelt! Menge: {1}",
                        ["Error"] = "Ein Fehler ist aufgetreten: {0}"
                    };
                case "fr":
                    return new Dictionary<string, string>
                    {
                        ["NoPermission"] = "Vous n'avez pas la permission d'utiliser cette commande!",
                        ["Usage"] = "Utilisation: /onehitfarm <on|off|status>",
                        ["Enabled"] = "OneHitFarm a été activé!",
                        ["Disabled"] = "OneHitFarm a été désactivé!",
                        ["Status"] = "OneHitFarm est actuellement {0}",
                        ["StatusEnabled"] = "activé",
                        ["StatusDisabled"] = "désactivé",
                        ["InvalidArg"] = "Argument invalide! Utilisation: /onehitfarm <on|off|status>",
                        ["ToolUsed"] = "Outil utilisé: {0}",
                        ["HitTree"] = "{0} a frappé un arbre!",
                        ["HitOre"] = "{0} a frappé un minerai!",
                        ["ResourceGathered"] = "{0} a récolté des ressources! Quantité: {1}",
                        ["Error"] = "Une erreur s'est produite: {0}"
                    };
                case "ru":
                    return new Dictionary<string, string>
                    {
                        ["NoPermission"] = "У вас нет разрешения использовать эту команду!",
                        ["Usage"] = "Использование: /onehitfarm <on|off|status>",
                        ["Enabled"] = "OneHitFarm был включен!",
                        ["Disabled"] = "OneHitFarm был отключен!",
                        ["Status"] = "OneHitFarm сейчас {0}",
                        ["StatusEnabled"] = "включен",
                        ["StatusDisabled"] = "выключен",
                        ["InvalidArg"] = "Неверный аргумент! Использование: /onehitfarm <on|off|status>",
                        ["ToolUsed"] = "Использованный инструмент: {0}",
                        ["HitTree"] = "{0} ударил дерево!",
                        ["HitOre"] = "{0} ударил руду!",
                        ["ResourceGathered"] = "{0} собрал ресурсы! Количество: {1}",
                        ["Error"] = "Произошла ошибка: {0}"
                    };
                default:
                    return new Dictionary<string, string>
                    {
                        ["NoPermission"] = "You don't have permission to use this command!",
                        ["Usage"] = "Usage: /onehitfarm <on|off|status>",
                        ["Enabled"] = "OneHitFarm has been enabled!",
                        ["Disabled"] = "OneHitFarm has been disabled!",
                        ["Status"] = "OneHitFarm is currently {0}",
                        ["StatusEnabled"] = "enabled",
                        ["StatusDisabled"] = "disabled",
                        ["InvalidArg"] = "Invalid argument! Usage: /onehitfarm <on|off|status>",
                        ["ToolUsed"] = "Tool used: {0}",
                        ["HitTree"] = "{0} hit a tree!",
                        ["HitOre"] = "{0} hit an ore!",
                        ["ResourceGathered"] = "{0} gathered resources! Amount: {1}",
                        ["Error"] = "An error occurred: {0}"
                    };
            }
        }

        private string Lang(string key, string userId = null, params object[] args)
        {
            try
            {
                return string.Format(lang.GetMessage(key, this, userId), args);
            }
            catch (Exception)
            {
                return key;
            }
        }
        #endregion

        #region Helper Methods
        private void LogError(string message)
        {
            // Loglama devre dışı
            return;
        }

        private void LogInfo(string message)
        {
            // Loglama devre dışı
            return;
        }

        private bool IsCompatibleVersion()
        {
            return true;
        }

        private void LogPerformance(string methodName, long startTime)
        {
            // Loglama devre dışı
            return;
        }

        private bool IsWithinGatherLimit(BasePlayer player)
        {
            if (player == null) return false;
            
            // Anti-cheat checks
            if (!player.IsConnected || player.IsSleeping() || player.IsSpectating())
                return false;
                
            // Player health status check
            if (player.IsDead() || player.IsWounded())
                return false;

            return true;
        }
        #endregion

        #region Core Methods
        private bool HasAllowedTool(BasePlayer player)
        {
            if (!configData.RequireTool) return true;
            if (player == null || !player.IsConnected || player.IsDead()) return false;

            try
            {
                Item activeItem = player.GetActiveItem();
                if (activeItem?.info == null) return false;

                // Geçerli alet kontrolü
                if (activeItem.info.category != ItemCategory.Tool && 
                    activeItem.info.category != ItemCategory.Weapon)
                    return false;

                // Durabilite kontrolü
                if (activeItem.hasCondition && activeItem.condition <= 0)
                    return false;

                return true;
            }
            catch (Exception ex)
            {
                if (configData.EnableLogging)
                    LogError($"HasAllowedTool error: {ex.Message}");
                return false;
            }
        }

        private void ProcessResource(BaseEntity entity, BasePlayer player)
        {
            if (!isInitialized || !configData.Enabled || entity == null || player == null) return;

            try
            {
                if (!IsWithinGatherLimit(player)) return;
                
                float distance = Vector3.Distance(player.transform.position, entity.transform.position);
                if (distance > configData.MaxGatherDistance)
                {
                    if (configData.EnableLogging)
                        LogInfo($"Player {player.displayName} tried to gather from too far away: {distance}m");
                    return;
                }

                // Performans için tip kontrolünü optimize et
                if (entity is TreeEntity tree && !tree.IsDestroyed)
                {
                    ProcessTree(tree, player);
                    return;
                }

                if (entity is ResourceEntity resource && !resource.IsDestroyed)
                {
                    ProcessOre(resource, player);
                }
            }
            catch (Exception ex)
            {
                LogError($"ProcessResource error: {ex.Message}");
            }
        }

        private void ProcessTree(TreeEntity tree, BasePlayer player)
        {
            if (tree == null || tree.IsDestroyed) return;

            try
            {
                if (tree.health <= MIN_HEALTH) return;

                var tool = player.GetActiveItem();
                if (tool == null) return;

                // Config ayarlarını al
                ToolSettings toolSettings = tool.info.shortname.Contains("rock") 
                    ? configData.ResourceSettings.Rock 
                    : configData.ResourceSettings.Tools;

                if (!toolSettings.Enabled) return;

                // Gather Manager çarpanını al
                float gatherManagerMultiplier = 1f;
                var gatherManager = plugins.Find("GatherManager");
                if (gatherManager != null)
                {
                    try
                    {
                        gatherManagerMultiplier = Convert.ToSingle(gatherManager.Call("GetGatherMultiplier", "wood"));
                        if (configData.EnableLogging)
                            LogInfo($"GatherManager multiplier for wood: {gatherManagerMultiplier}");
                    }
                    catch (Exception ex)
                    {
                        LogError($"GatherManager error in ProcessTree: {ex.Message}");
                    }
                }

                // Ağaç toplama işlemi
                var dispenser = tree.GetComponent<ResourceDispenser>();
                if (dispenser != null)
                {
                    var hit = CreateHitInfo(player, tree, tool);

                    // Çarpanları hesapla
                    float baseMultiplier = configData.ResourceSettings.ResourceTypes.Tree.BaseMultiplier;
                    float toolMultiplier = toolSettings.GatherMultiplier;
                    float finalMultiplier = (baseMultiplier * toolMultiplier) / gatherManagerMultiplier;

                    // Hit info'yu ayarla
                    hit.gatherScale = finalMultiplier;
                    hit.damageTypes.Add(tool.info.shortname.Contains("rock") ? DamageType.Blunt : DamageType.Generic, toolSettings.DamageAmount);

                    // Cache contained items
                    var containedItems = dispenser.containedItems?.ToList();
                    if (containedItems != null && containedItems.Count > 0)
                    {
                        for (int i = 0; i < toolSettings.GatherAttempts; i++)
                        {
                            foreach (var item in containedItems)
                            {
                                if (item == null || item.amount <= 0) continue;

                                try
                                {
                                    var itemDef = ItemManager.FindItemDefinition(item.itemid);
                                    if (itemDef == null) continue;

                                    int amount = Mathf.CeilToInt(item.amount * finalMultiplier);
                                    amount = Mathf.Min(amount, configData.ResourceSettings.ResourceTypes.Tree.MaxAmount);
                                    amount = Mathf.Max(configData.ResourceSettings.ResourceTypes.Tree.MinAmount, amount);

                                    if (amount > 0)
                                    {
                                        // Perform gather
                                        dispenser.OnAttacked(hit);

                                        // Give item to player
                                        Item collect = ItemManager.Create(itemDef, amount, 0uL);
                                        if (!collect.MoveToContainer(player.inventory.containerMain))
                                        {
                                            collect.Drop(player.GetDropPosition(), player.GetDropVelocity());
                                        }

                                        // Show gather amount
                                        player.Command("note.inv", new object[] { itemDef.itemid, amount });

                                        if (configData.EnableLogging)
                                        {
                                            LogInfo($"Tree gathered\n" +
                                                   $"Base Amount: {item.amount}\n" +
                                                   $"GatherManager Multiplier: {gatherManagerMultiplier}\n" +
                                                   $"Base Multiplier: {baseMultiplier}\n" +
                                                   $"Tool Multiplier: {toolMultiplier}\n" +
                                                   $"Final Multiplier: {finalMultiplier}\n" +
                                                   $"Final Amount: {amount}");
                                        }
                                    }
                                }
                                catch (Exception itemEx)
                                {
                                    LogError($"Tree item processing error: {itemEx.Message}");
                                }
                            }
                        }
                    }

                    // Show effects
                    if (toolSettings.ShowGatherEffects)
                    {
                        var effectPrefab = configData.ResourceSettings.ResourceTypes.Tree.EffectPrefab;
                        if (!string.IsNullOrEmpty(effectPrefab))
                        {
                            Effect.server.Run(effectPrefab, tree.transform.position, Vector3.up, null, false);
                        }
                    }

                    // Process custom drops
                    ProcessCustomDrops(player, configData.ResourceSettings.ResourceTypes.Tree);
                }

                // Destroy tree
                tree.health = MIN_HEALTH;
                NextTick(() => 
                {
                    if (tree != null && !tree.IsDestroyed)
                    {
                        tree.Kill(BaseNetworkable.DestroyMode.Gib);
                    }
                });
            }
            catch (Exception ex)
            {
                LogError($"ProcessTree error: {ex.Message}");
            }
        }

        private void ProcessOre(ResourceEntity resource, BasePlayer player)
        {
            if (resource == null || resource.IsDestroyed || player == null) return;

            try
            {
                var dispenser = resource.GetComponent<ResourceDispenser>();
                if (dispenser == null) return;

                var tool = player.GetActiveItem();
                if (tool == null || tool.GetHeldEntity() == null) return;

                if (resource.health <= MIN_HEALTH) return;

                // Determine resource type
                ResourceTypeConfig resourceConfig = null;
                string effectPrefab = "";
                string resourceType = "";

                if (resource.ShortPrefabName.Contains("sulfur", StringComparison.OrdinalIgnoreCase))
                {
                    resourceConfig = configData.ResourceSettings.ResourceTypes.Sulfur;
                    resourceType = "sulfur.ore";
                    effectPrefab = resourceConfig.EffectPrefab;
                }
                else if (resource.ShortPrefabName.Contains("metal", StringComparison.OrdinalIgnoreCase))
                {
                    resourceConfig = configData.ResourceSettings.ResourceTypes.Metal;
                    resourceType = "metal.ore";
                    effectPrefab = resourceConfig.EffectPrefab;
                }
                else if (resource.ShortPrefabName.Contains("stone", StringComparison.OrdinalIgnoreCase))
                {
                    resourceConfig = configData.ResourceSettings.ResourceTypes.Stone;
                    resourceType = "stone";
                    effectPrefab = resourceConfig.EffectPrefab;
                }

                if (resourceConfig == null || !resourceConfig.Enabled) return;

                // Get tool settings
                ToolSettings toolSettings = tool.info.shortname.Contains("rock") 
                    ? configData.ResourceSettings.Rock 
                    : configData.ResourceSettings.Tools;

                if (!toolSettings.Enabled) return;

                // Gather Manager çarpanını al
                float gatherManagerMultiplier = 1f;
                var gatherManager = plugins.Find("GatherManager");
                if (gatherManager != null)
                {
                    try
                    {
                        gatherManagerMultiplier = Convert.ToSingle(gatherManager.Call("GetGatherMultiplier", resourceType));
                        if (configData.EnableLogging)
                            LogInfo($"GatherManager multiplier for {resourceType}: {gatherManagerMultiplier}");
                    }
                    catch (Exception ex)
                    {
                        LogError($"GatherManager error: {ex.Message}");
                    }
                }

                // Create HitInfo once and reuse
                var hit = CreateHitInfo(player, resource, tool);

                // Çarpanları hesapla
                float baseMultiplier = resourceConfig.BaseMultiplier;
                float toolMultiplier = toolSettings.GatherMultiplier;
                float finalMultiplier = (baseMultiplier * toolMultiplier) / gatherManagerMultiplier;

                // Hit info'yu ayarla
                hit.gatherScale = finalMultiplier;
                hit.damageTypes.Add(tool.info.shortname.Contains("rock") ? DamageType.Blunt : DamageType.Generic, toolSettings.DamageAmount);

                // Cache contained items
                var containedItems = dispenser.containedItems?.ToList();
                if (containedItems == null || containedItems.Count == 0) return;

                // Gather işlemi
                for (int i = 0; i < toolSettings.GatherAttempts; i++)
                {
                    foreach (var item in containedItems)
                    {
                        if (item == null || item.amount <= 0) continue;

                        try
                        {
                            var itemDef = ItemManager.FindItemDefinition(item.itemid);
                            if (itemDef == null) continue;

                            int amount = Mathf.CeilToInt(item.amount * finalMultiplier);
                            amount = Mathf.Min(amount, resourceConfig.MaxAmount);
                            amount = Mathf.Max(resourceConfig.MinAmount, amount);

                            if (amount > 0)
                            {
                                // Perform gather
                                dispenser.OnAttacked(hit);

                                // Give item to player
                                Item collect = ItemManager.Create(itemDef, amount, 0uL);
                                if (!collect.MoveToContainer(player.inventory.containerMain))
                                {
                                    collect.Drop(player.GetDropPosition(), player.GetDropVelocity());
                                }

                                // Show gather amount
                                player.Command("note.inv", new object[] { itemDef.itemid, amount });

                                if (configData.EnableLogging)
                                {
                                    LogGatherInfo(resourceType, item.amount, gatherManagerMultiplier, baseMultiplier, toolMultiplier, finalMultiplier, amount, 0, 0);
                                }
                            }
                        }
                        catch (Exception itemEx)
                        {
                            LogError($"Item processing error: {itemEx.Message}");
                        }
                    }
                }

                // Show effects
                if (toolSettings.ShowGatherEffects && !string.IsNullOrEmpty(effectPrefab))
                {
                    Effect.server.Run(effectPrefab, resource.transform.position, Vector3.up, null, false);
                }

                // Process custom drops
                ProcessCustomDrops(player, resourceConfig);

                // Destroy resource
                DestroyResource(resource);
            }
            catch (Exception ex)
            {
                LogError($"ProcessOre error: {ex.Message}");
            }
        }

        private void DestroyResource(ResourceEntity resource)
        {
            if (resource == null) return;
            
            resource.health = MIN_HEALTH;
            NextTick(() => 
            {
                if (resource != null && !resource.IsDestroyed)
                {
                    resource.Kill(BaseNetworkable.DestroyMode.Gib);
                }
            });
        }

        private HitInfo CreateHitInfo(BasePlayer player, BaseEntity resource, Item tool)
        {
            var hit = new HitInfo
            {
                Initiator = player,
                HitEntity = resource,
                HitPositionWorld = resource.transform.position,
                HitNormalWorld = Vector3.up,
                HitMaterial = StringPool.Get("Rock"),
                WeaponPrefab = tool.GetHeldEntity(),
                damageTypes = new DamageTypeList(),
                DoHitEffects = true,
                DidHit = true,
                PointStart = player.transform.position,
                PointEnd = resource.transform.position
            };

            // Optimize edilmiş gather scale hesaplama
            var resourceConfig = GetResourceType(resource);
            hit.gatherScale = tool.info.shortname.Contains("rock") 
                ? configData.ResourceSettings.Rock.GatherMultiplier
                : (resourceConfig?.BaseMultiplier ?? configData.ResourceSettings.Tools.GatherMultiplier);

            return hit;
        }

        private ResourceTypeConfig GetResourceType(BaseEntity resource)
        {
            if (resource == null) return null;

            var shortName = resource.ShortPrefabName.ToLower();
            
            if (shortName.Contains("sulfur"))
                return configData.ResourceSettings.ResourceTypes.Sulfur;
            if (shortName.Contains("metal"))
                return configData.ResourceSettings.ResourceTypes.Metal;
            if (shortName.Contains("stone"))
                return configData.ResourceSettings.ResourceTypes.Stone;
            if (shortName.Contains("tree") || shortName.Contains("wood"))
                return configData.ResourceSettings.ResourceTypes.Tree;

            return null;
        }

        protected override void SaveConfig()
        {
            if (configData == null)
                configData = new ConfigData();

            Config.WriteObject(configData, true);
        }

        private void InitializePlugin()
        {
            try
            {
                // Permission'ları sadece kayıtlı değillerse kaydet
                if (!permission.PermissionExists(PERMISSION_USE))
                    permission.RegisterPermission(PERMISSION_USE, this);
                    
                if (!permission.PermissionExists(PERMISSION_ADMIN))
                    permission.RegisterPermission(PERMISSION_ADMIN, this);
                
                LoadDefaultMessages();
                
                isInitialized = true;
                isLoaded = true;

                if (configData.EnableLogging)
                    LogInfo($"Plugin initialized successfully.Version: {Version}");
            }
            catch (Exception ex)
            {
                PrintError($"Failed to initialize plugin: {ex.Message}");
                isInitialized = false;
                isLoaded = false;
            }
        }

        private void OnServerInitialized()
        {
            InitializePlugin();
        }

        private void Unload()
        {
            // SaveConfig kaldırıldı
        }

        private void ProcessTreeGather(TreeEntity tree, BasePlayer player, Item tool, ResourceTypeConfig treeConfig)
        {
            if (tree == null || player == null || tool == null || treeConfig == null) return;

            var dispenser = tree.GetComponent<ResourceDispenser>();
            if (dispenser == null) return;

            var toolSettings = tool.info.shortname.Contains("rock") 
                ? configData.ResourceSettings.Rock 
                : configData.ResourceSettings.Tools;

            var hit = CreateHitInfo(player, tree, tool);
            hit.damageTypes.Add(tool.info.shortname.Contains("rock") ? DamageType.Blunt : DamageType.Generic, toolSettings.DamageAmount);

            for (int i = 0; i < toolSettings.GatherAttempts; i++)
            {
                dispenser.OnAttacked(hit);
            }

            // Efektleri göster
            if (toolSettings.ShowGatherEffects && !string.IsNullOrEmpty(treeConfig.EffectPrefab))
            {
                Effect.server.Run(
                    treeConfig.EffectPrefab,
                    tree.transform.position,
                    Vector3.up,
                    null,
                    false
                );
            }

            // Özel dropları işle
            ProcessCustomDrops(player, treeConfig);
        }

        private void ProcessCustomDrops(BasePlayer player, ResourceTypeConfig resourceConfig)
        {
            if (player == null || resourceConfig?.CustomDrops == null) return;

            foreach (var customDrop in resourceConfig.CustomDrops)
            {
                if (UnityEngine.Random.value <= customDrop.Chance)
                {
                    var itemDef = ItemManager.FindItemDefinition(customDrop.ItemShortName);
                    if (itemDef != null)
                    {
                        int amount = UnityEngine.Random.Range(customDrop.MinAmount, customDrop.MaxAmount + 1);
                        var item = ItemManager.Create(itemDef, amount, 0uL);
                        if (!item.MoveToContainer(player.inventory.containerMain))
                        {
                            item.Drop(player.GetDropPosition(), player.GetDropVelocity());
                        }
                    }
                }
            }
        }

        private float CalculateMultiplier(float baseAmount, float gatherManagerMultiplier, float baseMultiplier, float toolMultiplier)
        {
            if (gatherManagerMultiplier <= 0f) gatherManagerMultiplier = 1f;
            float normalAmount = baseAmount / gatherManagerMultiplier;
            return normalAmount * baseMultiplier * toolMultiplier;
        }

        private int CalculateFinalAmount(float calculatedAmount, int minAmount, int maxAmount, int maxStackSize)
        {
            return Mathf.Min(
                maxStackSize,
                Mathf.Min(
                    maxAmount,
                    Mathf.Max(
                        minAmount,
                        Mathf.CeilToInt(calculatedAmount)
                    )
                )
            );
        }
        #endregion

        #region Hooks
        object OnEntityTakeDamage(BaseEntity entity, HitInfo info)
        {
            if (!isInitialized || !configData.Enabled || entity == null || info?.InitiatorPlayer == null)
                return null;

            try
            {
                var player = info.InitiatorPlayer;

                if (configData.RequirePermission && !permission.UserHasPermission(player.UserIDString, PERMISSION_USE))
                    return null;

                if (!HasAllowedTool(player))
                    return null;

                // Tip kontrolünü optimize et
                if (entity is TreeEntity || entity is ResourceEntity)
                {
                    ProcessResource(entity, player);
                }
            }
            catch
            {
                // Sessizce devam et
            }
            return null;
        }

        void OnDispenserGather(ResourceDispenser dispenser, BaseEntity entity, Item item)
        {
            if (!isInitialized || !configData.Enabled || dispenser == null || entity == null || item == null)
                return;

            try
            {
                var player = entity.ToPlayer();
                if (player == null || !IsWithinGatherLimit(player)) return;

                if (configData.RequirePermission && !permission.UserHasPermission(player.UserIDString, PERMISSION_USE))
                    return;

                if (!HasAllowedTool(player))
                    return;

                if (dispenser.gatherType == ResourceDispenser.GatherType.Tree || 
                    dispenser.gatherType == ResourceDispenser.GatherType.Ore)
                {
                    int maxStackSize = item.MaxStackable();
                    if (maxStackSize <= 0) return;
                    
                    var tool = player.GetActiveItem();
                    if (tool == null) return;

                    // Başlangıç miktarını al (bu Gather Manager'ın etkilemediği ham miktar)
                    float baseAmount = item.amount;

                    // Kaynak tipini belirle
                    ResourceTypeConfig resourceConfig = null;
                    string resourceType = "";

                    if (dispenser.gatherType == ResourceDispenser.GatherType.Tree)
                    {
                        resourceConfig = configData.ResourceSettings.ResourceTypes.Tree;
                        resourceType = "wood";
                    }
                    else
                    {
                        string itemName = item.info.shortname.ToLower();
                        if (itemName.Contains("metal"))
                        {
                            resourceConfig = configData.ResourceSettings.ResourceTypes.Metal;
                            resourceType = "metal.ore";
                        }
                        else if (itemName.Contains("sulfur"))
                        {
                            resourceConfig = configData.ResourceSettings.ResourceTypes.Sulfur;
                            resourceType = "sulfur.ore";
                        }
                        else if (itemName.Contains("stone"))
                        {
                            resourceConfig = configData.ResourceSettings.ResourceTypes.Stone;
                            resourceType = "stone";
                        }
                    }

                    if (resourceConfig == null) return;

                    // Tool ayarlarını al
                    ToolSettings toolSettings = tool.info.shortname.Contains("rock") 
                        ? configData.ResourceSettings.Rock 
                        : configData.ResourceSettings.Tools;

                    // Gather Manager çarpanını al
                    float gatherManagerMultiplier = 1f;
                    var gatherManager = plugins.Find("GatherManager");
                    if (gatherManager != null)
                    {
                        try
                        {
                            gatherManagerMultiplier = Convert.ToSingle(gatherManager.Call("GetGatherMultiplier", resourceType));
                            if (configData.EnableLogging)
                                LogInfo($"GatherManager multiplier for {resourceType}: {gatherManagerMultiplier}");
                        }
                        catch (Exception ex)
                        {
                            LogError($"GatherManager error: {ex.Message}");
                        }
                    }

                    // Yeni hesaplama mantığı
                    float normalAmount = baseAmount / gatherManagerMultiplier; // GatherManager etkisini kaldır
                    float pluginMultiplier = resourceConfig.BaseMultiplier * toolSettings.GatherMultiplier;
                    int finalAmount = Mathf.CeilToInt(normalAmount * pluginMultiplier);

                    // Minimum miktar kontrolü
                    finalAmount = Mathf.Max(toolSettings.MinAmount, finalAmount);

                    // Maksimum miktar kontrolü
                    finalAmount = Mathf.Min(finalAmount, resourceConfig.MaxAmount);
                    finalAmount = Mathf.Min(finalAmount, maxStackSize);

                    // Sonucu uygula
                    item.amount = finalAmount;
                    item.MarkDirty();

                    // Gather miktarını göster
                    player.Command("note.inv", new object[] { item.info.itemid, finalAmount });

                    if (configData.EnableLogging)
                    {
                        LogGatherInfo(resourceType, baseAmount, gatherManagerMultiplier, resourceConfig.BaseMultiplier, toolSettings.GatherMultiplier, pluginMultiplier, finalAmount, maxStackSize, resourceConfig.MaxAmount);
                    }
                }
            }
            catch (Exception ex)
            {
                LogError($"OnDispenserGather error: {ex.Message}");
            }
        }
        #endregion

        #region Commands
        [ChatCommand("onehitfarm")]
        private void CmdOneHitFarm(BasePlayer player, string command, string[] args)
        {
            if (player == null) return;

            if (!isInitialized || !configData.Enabled)
            {
                SendReply(player, "Plugin is still initializing, please wait...");
                return;
            }

            if (!permission.UserHasPermission(player.UserIDString, PERMISSION_ADMIN))
            {
                SendReply(player, Lang("NoPermission", player.UserIDString));
                return;
            }

            if (args == null || args.Length == 0)
            {
                SendReply(player, Lang("Usage", player.UserIDString));
                return;
            }

            try
            {
                switch (args[0].ToLower())
                {
                    case "on":
                        if (configData.Enabled)
                        {
                            SendReply(player, "Plugin is already enabled!");
                            return;
                        }
                        configData.Enabled = true;
                        // SaveConfig kaldırıldı
                        SendReply(player, Lang("Enabled", player.UserIDString));
                        break;

                    case "off":
                        if (!configData.Enabled)
                        {
                            SendReply(player, "Plugin is already disabled!");
                            return;
                        }
                        configData.Enabled = false;
                        // SaveConfig kaldırıldı
                        SendReply(player, Lang("Disabled", player.UserIDString));
                        break;

                    case "status":
                        string status = configData.Enabled ? 
                            Lang("StatusEnabled", player.UserIDString) : 
                            Lang("StatusDisabled", player.UserIDString);
                        SendReply(player, Lang("Status", player.UserIDString, status));
                        break;

                    default:
                        SendReply(player, Lang("InvalidArg", player.UserIDString));
                        break;
                }
            }
            catch
            {
                SendReply(player, Lang("Error", player.UserIDString, "An error occurred."));
            }
        }
        #endregion

        private void LogGatherInfo(string resourceType, float baseAmount, float gatherManagerMultiplier, float baseMultiplier, float toolMultiplier, float finalMultiplier, int finalAmount, int maxStackSize = 0, int resourceMax =
// ... [Code preview truncated due to length. Full source in attached file] ...

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