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

FREE ZLevelsRemastered : 3.2.2 3.2.2

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

namespace Oxide.Plugins
{
    [Info("ZLevels Remastered", "nivex", "3.2.2")]
    [Description("Lets players level up as they harvest different resources and when crafting")]

    class ZLevelsRemastered : RustPlugin
    {
        [PluginReference]
        Plugin EventManager, CraftingController, ZoneManager, Economics, IQEconomic, ServerRewards, SkillTree;

        private StoredData data = new();
        private Dictionary<string, ItemDefinition> CraftItems;
        private CraftData _craftData = new();
        private StringBuilder _sb = new();
        private bool newSaveDetected;
        private bool bonusOn;
        private int MaxB = 10001;
        private int MinB = 10;

        public enum Skills
        {
            ACQUIRE,
            CRAFTING,
            MINING,
            SKINNING,
            WOODCUTTING,
            ALL
        }

        private Skills[] AllSkills = new Skills[] { Skills.ACQUIRE, Skills.CRAFTING, Skills.MINING, Skills.SKINNING, Skills.WOODCUTTING };

        private class CraftData
        {
            public Dictionary<string, CraftInfo> CraftList = new();
            public CraftData() { }
        }

        private class CraftInfo
        {
            public int MaxBulkCraft;
            public int MinBulkCraft;
            public string shortName;
            public bool Enabled;
            public CraftInfo() { }
        }

        private class StoredData
        {
            public Hash<ulong, PlayerInfo> PlayerInfo = new();
            public StoredData() { }
        }

        private enum LevelType
        {
            ACQUIRE_LEVEL,
            ACQUIRE_POINTS,
            CRAFTING_LEVEL,
            CRAFTING_POINTS,
            MINING_LEVEL,
            MINING_POINTS,
            WOODCUTTING_LEVEL,
            WOODCUTTING_POINTS,
            SKINNING_LEVEL,
            SKINNING_POINTS,
            LAST_DEATH,
            XP_MULTIPLIER,
        }

        private class PlayerInfo : IEquatable<PlayerInfo>
        {
            private double _acquireLevel = 1.0;
            private double _acquirePoints = 10.0;
            private double _craftingLevel = 1.0;
            private double _craftingPoints = 10.0;
            private double _miningLevel = 1.0;
            private double _miningPoints = 10.0;
            private double _skinningLevel = 1.0;
            private double _skinningPoints = 10.0;
            private double _woodcuttingLevel = 1.0;
            private double _woodcuttingPoints = 10.0;
            private double _lastDeath = 0.0;
            private double _xpMultiplier = 100.0;

            private double RoundValue(double value) => Math.Round(value, 2, MidpointRounding.AwayFromZero);

            [JsonProperty(PropertyName = "AL")]
            public double ACQUIRE_LEVEL
            {
                get => RoundValue(_acquireLevel);
                set => _acquireLevel = RoundValue(value);
            }

            [JsonProperty(PropertyName = "AP")]
            public double ACQUIRE_POINTS
            {
                get => RoundValue(_acquirePoints);
                set => _acquirePoints = RoundValue(value);
            }

            [JsonProperty(PropertyName = "CL")]
            public double CRAFTING_LEVEL
            {
                get => RoundValue(_craftingLevel);
                set => _craftingLevel = RoundValue(value);
            }

            [JsonProperty(PropertyName = "CP")]
            public double CRAFTING_POINTS
            {
                get => RoundValue(_craftingPoints);
                set => _craftingPoints = RoundValue(value);
            }

            [JsonProperty(PropertyName = "ML")]
            public double MINING_LEVEL
            {
                get => RoundValue(_miningLevel);
                set => _miningLevel = RoundValue(value);
            }

            [JsonProperty(PropertyName = "MP")]
            public double MINING_POINTS
            {
                get => RoundValue(_miningPoints);
                set => _miningPoints = RoundValue(value);
            }

            [JsonProperty(PropertyName = "SL")]
            public double SKINNING_LEVEL
            {
                get => RoundValue(_skinningLevel);
                set => _skinningLevel = RoundValue(value);
            }

            [JsonProperty(PropertyName = "SP")]
            public double SKINNING_POINTS
            {
                get => RoundValue(_skinningPoints);
                set => _skinningPoints = RoundValue(value);
            }

            [JsonProperty(PropertyName = "WCL")]
            public double WOODCUTTING_LEVEL
            {
                get => RoundValue(_woodcuttingLevel);
                set => _woodcuttingLevel = RoundValue(value);
            }

            [JsonProperty(PropertyName = "WCP")]
            public double WOODCUTTING_POINTS
            {
                get => RoundValue(_woodcuttingPoints);
                set => _woodcuttingPoints = RoundValue(value);
            }

            [JsonProperty(PropertyName = "LD")]
            public double LAST_DEATH
            {
                get => RoundValue(_lastDeath);
                set => _lastDeath = RoundValue(value);
            }

            [JsonProperty(PropertyName = "XPM")]
            public double XP_MULTIPLIER
            {
                get => RoundValue(_xpMultiplier);
                set => _xpMultiplier = RoundValue(value);
            }

            [JsonProperty(PropertyName = "CUI")]
            public bool CUI { get; set; } = true;

            [JsonProperty(PropertyName = "ONOFF")]
            public bool ENABLED { get; set; } = true;

            public PlayerInfo() { }

            public bool Equals(PlayerInfo other)
            {
                if (other == null)
                    return false;

                return ACQUIRE_LEVEL == other.ACQUIRE_LEVEL &&
                       ACQUIRE_POINTS == other.ACQUIRE_POINTS &&
                       CRAFTING_LEVEL == other.CRAFTING_LEVEL &&
                       CRAFTING_POINTS == other.CRAFTING_POINTS &&
                       MINING_LEVEL == other.MINING_LEVEL &&
                       MINING_POINTS == other.MINING_POINTS &&
                       SKINNING_LEVEL == other.SKINNING_LEVEL &&
                       SKINNING_POINTS == other.SKINNING_POINTS &&
                       WOODCUTTING_LEVEL == other.WOODCUTTING_LEVEL &&
                       WOODCUTTING_POINTS == other.WOODCUTTING_POINTS &&
                       XP_MULTIPLIER == other.XP_MULTIPLIER &&
                       CUI == other.CUI &&
                       ENABLED == other.ENABLED;
            }

            public override bool Equals(object obj)
            {
                return obj is PlayerInfo other && Equals(other);
            }

            public override int GetHashCode()
            {
                HashCode hash = new();
                hash.Add(ACQUIRE_LEVEL);
                hash.Add(ACQUIRE_POINTS);
                hash.Add(CRAFTING_LEVEL);
                hash.Add(CRAFTING_POINTS);
                hash.Add(MINING_LEVEL);
                hash.Add(MINING_POINTS);
                hash.Add(SKINNING_LEVEL);
                hash.Add(SKINNING_POINTS);
                hash.Add(WOODCUTTING_LEVEL);
                hash.Add(WOODCUTTING_POINTS);
                hash.Add(XP_MULTIPLIER);
                hash.Add(CUI);
                hash.Add(ENABLED);
                return hash.ToHashCode();
            }

            public static bool operator ==(PlayerInfo left, PlayerInfo right)
            {
                if (ReferenceEquals(left, right))
                    return true;

                if (left is null)
                    return false;

                return left.Equals(right);
            }

            public static bool operator !=(PlayerInfo left, PlayerInfo right)
            {
                return !(left == right);
            }

            internal bool IsDefault(PlayerInfo other) => Equals(other);
        }

        #region Main

        private void Init()
        {
            Unsubscribe();
            RegisterPermissions();

            int index = 0;

            foreach (Skills skill in AllSkills)
            {
                if (IsSkillEnabled(skill))
                {
                    skillIndex.Add(skill, ++index);
                }
            }
        }

        private void Unload()
        {
            Clean();
            SaveData();
            foreach (var player in BasePlayer.activePlayerList)
            {
                DestroyGUI(player);
            }
            if (TOD_Sky.Instance?.Components?.Time != null)
            {
                TOD_Sky.Instance.Components.Time.OnSunrise -= OnTimeSunrise;
                TOD_Sky.Instance.Components.Time.OnSunset -= OnTimeSunset;
            }
        }

        private void OnNewSave(string strFilename)
        {
            if (config.generic.wipeDataOnNewSave)
            {
                Puts("New save detected...");
                newSaveDetected = true;
            }
        }

        private void OnServerInitialized()
        {
            LoadData();
            if (config.nightbonus.enableNightBonus && TOD_Sky.Instance.IsNight)
            {
                pointsPerHitCurrent = config.nightbonus.pointsPerHitAtNight;
                resourceMultipliersCurrent = config.nightbonus.resourceMultipliersAtNight;
                pointsPerHitPowerToolCurrent = config.nightbonus.pointsPerPowerToolAtNight;
                bonusOn = true;
            }
            else
            {
                pointsPerHitCurrent = config.settings.pointsPerHit;
                resourceMultipliersCurrent = config.settings.resourceMultipliers;
                pointsPerHitPowerToolCurrent = config.settings.pointsPerPowerTool;
            }

            foreach (var player in BasePlayer.allPlayerList)
            {
                var pi = GetPlayerInfo(player);
                if (player.IsConnected) CreateGUI(player, pi);
            }

            Puts("Stats can be reset by > zl.reset <");
            Subscribe();
            SaveData();
            RegisterCommands();
        }

        private void OnPlayerConnected(BasePlayer player) => OnPlayerSleepEnded(player);

        private void OnPlayerDisconnected(BasePlayer player) => GetPlayerInfo(player);

        private void OnEntityKill(BasePlayer player) => OnPlayerSleep(player);

        private void OnPlayerRespawned(BasePlayer player) => OnPlayerSleepEnded(player);

        private void OnPlayerSleepEnded(BasePlayer player) => CreateGUI(player, GetPlayerInfo(player));

        private void OnPlayerSleep(BasePlayer player) => DestroyGUI(player);

        private void OnEntityDeath(BasePlayer player, HitInfo hitInfo)
        {
            if (hitInfo == null || !IsValid(player) || isZoneExcluded(player))
            {
                return;
            }

            DestroyGUI(player);

            if (!hasRights(player.UserIDString))
            {
                return;
            }

            var pi = GetPlayerInfo(player);

            if (!pi.ENABLED || permission.UserHasPermission(player.UserIDString, config.generic.permissionNameXP))
            {
                return;
            }

            bool isSuicide = hitInfo.damageTypes.Has(DamageType.Suicide) && (player.IsAdmin || player.IsDeveloper || !player.CanSuicide());

            if (!config.generic.penaltyOnSuicide && isSuicide) return;
            if (!config.generic.penaltyOnDeath && !isSuicide) return;

            if (EventManager?.Call("IsEventPlayer", player) != null)
            {
                return;
            }

            if (Interface.CallHook("CanBePenalized", player) != null)
            {
                return;
            }

            _sb.Clear();

            foreach (Skills skill in AllSkills)
            {
                if (IsSkillEnabled(skill))
                {
                    var penalty = GetPenalty(player, pi, skill, isSuicide);

                    if (penalty > 0)
                    {
                        _sb.AppendLine("* -" + penalty + " " + _(skill + "Skill") + " XP.");
                        removePoints(pi, skill, penalty);
                    }
                }
            }
            
            if (_sb.Length > 0)
            {
                Message(player, "PenaltyText", _sb.ToString());
            }

            pi.LAST_DEATH = ToEpochTime(DateTime.UtcNow);
        }

        private void OnDispenserGather(ResourceDispenser dispenser, BasePlayer player, Item item)
        {
            if (item == null || dispenser == null || !IsValid(player) || !hasRights(player.UserIDString))
            {
                return;
            }

            Skills? skill = dispenser.gatherType switch
            {
                ResourceDispenser.GatherType.Tree => Skills.WOODCUTTING,
                ResourceDispenser.GatherType.Flesh => Skills.SKINNING,
                ResourceDispenser.GatherType.Ore => Skills.MINING,
                _ => null
            };

            if (skill == null || !IsSkillEnabled(skill.Value))
            {
                return;
            }

            var pi = GetPlayerInfo(player);

            if (!pi.ENABLED)
            {
                return;
            }

            Item activeItem = player.GetActiveItem();

            if (permission.UserHasPermission(player.UserIDString, config.generic.BlockWeaponsGather) && activeItem?.info.category == ItemCategory.Weapon)
            {
                return;
            }

            if (!config.functions.ShouldAllowGather(item.info.shortname, out bool grantXPOnly))
            {
                return;
            }

            int prevAmount = item.amount;
            bool isPowerTool = false;
            
            if (skill != Skills.SKINNING && activeItem != null)
            {
                HeldEntity heldEntity = activeItem.GetHeldEntity() as HeldEntity;

                if (heldEntity is Jackhammer || heldEntity is Chainsaw)
                {
                    if (skill == Skills.WOODCUTTING && !CanUseChainsaw(player))
                    {
                        return;
                    }

                    if (skill == Skills.MINING && !CanUseJackhammer(player))
                    {
                        return;
                    }

                    if (!config.functions.gibs && dispenser.GetComponent<ServerGib>() != null)
                    {
                        return;
                    }

                    isPowerTool = true;
                }
            }

            if (!config.functions.gibs && skill == Skills.MINING && dispenser.GetComponent<ServerGib>() != null)
            {
                return;
            }

            int amount = levelHandler(pi, player, item.amount, skill.Value, dispenser.baseEntity, isPowerTool);

            if (!grantXPOnly)
            {
                item.amount = amount;
            }

            if (item.amount != prevAmount)
            {
                Interface.CallHook("OnZLevelDispenserGather", dispenser, player, item, prevAmount, item.amount, isPowerTool);
            }
        }

        private bool CanUseJackhammer(BasePlayer player) => permission.UserHasPermission(player.UserIDString, config.generic.AllowJackhammerGather);

        private bool CanUseChainsaw(BasePlayer player) => permission.UserHasPermission(player.UserIDString, config.generic.AllowChainsawGather);

        private void OnDispenserBonus(ResourceDispenser dispenser, BasePlayer player, Item item) => OnDispenserGather(dispenser, player, item);

        private List<string> _warnings = new();

        private object OnCollectiblePickup(CollectibleEntity collectible, BasePlayer player)
        {
            if (collectible == null || collectible.itemList.IsNullOrEmpty() || !IsValid(player) || !hasRights(player.UserIDString))
                return null;

            var pi = GetPlayerInfo(player);

            if (pi == null || !pi.ENABLED)
                return null;

            if (config.functions.enabledCollectibleEntity.TryGetValue(collectible.ShortPrefabName, out var enabled) && !enabled)
                return null;

            Skills skill;

            for (int i = 0; i < collectible.itemList.Length; i++)
            {
                ItemAmount itemAmount = collectible.itemList[i];
                if (itemAmount == null) continue;
                if (itemAmount.itemDef == null) continue;
                switch (itemAmount.itemDef.shortname)
                {
                    case "black.berry":
                    case "blue.berry":
                    case "bone.fragments":
                    case "clone.seed":
                    case "clone.orchid":
                    case "clone.rose":
                    case "clone.sunflower":
                    case "cloth":
                    case "corn":
                    case "diesel_barrel":
                    case "green.berry":
                    case "mushroom":
                    case "orchid":
                    case "potato":
                    case "pumpkin":
                    case "red.berry":
                    case "rose":
                    case "seed.black.berry":
                    case "seed.blue.berry":
                    case "seed.corn":
                    case "seed.green.berry":
                    case "seed.hemp":
                    case "seed.orchid":
                    case "seed.potato":
                    case "seed.pumpkin":
                    case "seed.red.berry":
                    case "seed.rose":
                    case "seed.sunflower":
                    case "seed.wheat":
                    case "seed.white.berry":
                    case "seed.yellow.berry":
                    case "sunflower":
                    case "wheat":
                    case "white.berry":
                    case "yellow.berry":
                        skill = IsSkillEnabled(Skills.ACQUIRE) ? Skills.ACQUIRE : Skills.SKINNING;
                        break;
                    case "metal.ore":
                    case "sulfur.ore":
                    case "stones":
                        skill = config.settings.MiningStonesOre ? Skills.MINING : Skills.ACQUIRE;
                        break;
                    case "wood":
                        skill = config.settings.AcquireWood ? Skills.ACQUIRE : Skills.WOODCUTTING;
                        break;
                    default:
                        if (IsSkillEnabled(Skills.ACQUIRE)) skill = Skills.ACQUIRE;
                        else if (IsSkillEnabled(Skills.SKINNING)) skill = Skills.SKINNING;
                        else return null;
                        if (!_warnings.Contains(itemAmount.itemDef.shortname))
                        {
                            PrintWarning($"WARNING: {player} picked up undefined item: {itemAmount.itemDef.shortname}.Defaulting to {skill} skill.");
                            _warnings.Add(itemAmount.itemDef.shortname);
                        }
                        break;
                }

                if (IsSkillEnabled(skill))
                {
                    int prevAmount = (int)itemAmount.amount;
                    itemAmount.amount = levelHandler(pi, player, prevAmount, skill, collectible);
                    if (Interface.CallHook("OnZLevelCollectiblePickup", itemAmount, player, collectible, prevAmount, itemAmount.amount) != null)
                    {
                        return true;
                    }
                }
            }
            return null;
        }

        private void OnTimeSunset()
        {
            if (!config.nightbonus.enableNightBonus || bonusOn)
            {
                return;
            }

            bonusOn = true;
            pointsPerHitCurrent = config.nightbonus.pointsPerHitAtNight;
            resourceMultipliersCurrent = config.nightbonus.resourceMultipliersAtNight;
            pointsPerHitPowerToolCurrent = config.nightbonus.pointsPerPowerToolAtNight;
            if (config.nightbonus.broadcastEnabledBonus)
            {
                foreach (var player in BasePlayer.activePlayerList)
                    Message(player, "NightBonusOn");
            }
            if (config.nightbonus.logEnabledBonusConsole)
                Puts("Nightbonus points enabled");
        }

        private void OnTimeSunrise()
        {
            if (!config.nightbonus.enableNightBonus || !bonusOn)
            {
                return;
            }
            bonusOn = false;
            pointsPerHitCurrent = config.settings.pointsPerHit;
            resourceMultipliersCurrent = config.settings.resourceMultipliers;
            pointsPerHitPowerToolCurrent = config.settings.pointsPerPowerTool;
            if (config.nightbonus.broadcastEnabledBonus)
            {
                foreach (var player in BasePlayer.activePlayerList)
                    Message(player, "NightBonusOff");
            }
            if (config.nightbonus.logEnabledBonusConsole)
                Puts("Nightbonus points disabled");
        }

        private object OnGrowableGathered(GrowableEntity plant, Item item, BasePlayer player)
        {
            if (item == null || player == null || !hasRights(player.UserIDString))
            {
                return true;
            }

            var pi = GetPlayerInfo(player);

            if (!pi.ENABLED)
            {
                return true;
            }

            Skills skill;
            if (IsSkillEnabled(Skills.ACQUIRE))
                skill = Skills.ACQUIRE;
            else skill = Skills.SKINNING;

            var prevAmount = item.amount;

            item.amount = levelHandler(pi, player, item.amount, skill, plant);

            Interface.CallHook("OnZLevelGrowableGathered", plant, item, player, prevAmount, item.amount);

            return null;
        }


        private object OnItemCraft(ItemCraftTask task, BasePlayer crafter, Item fromTempBlueprint)
        {
            if (!hasRights(crafter.UserIDString)) return null;

            var pi = GetPlayerInfo(crafter);

            if (!pi.ENABLED) return null;

            var bypassCraftLevelRequirement = CanInstantCraftNoLevelRequirement(crafter);
            var craftingTime = task.blueprint.time;

            if (bypassCraftLevelRequirement)
            {
                craftingTime = 0;
            }
            else if (IsSkillEnabled(Skills.CRAFTING))
            {
                if (pi.CRAFTING_LEVEL > 1)
                    craftingTime -= task.blueprint.time * (float)((pi.CRAFTING_LEVEL * config.settings.craftingDetails.percent) / 100);
            }
            else return null;

            if (craftingTime <= 0)
            {
                craftingTime = 0;

                foreach (var craftInfo in _craftData.CraftList.Values)
                {
                    if (!craftInfo.Enabled || craftInfo.shortName != task.blueprint.targetItem.shortname)
                    {
                        continue;
                    }
                    if (task.amount >= craftInfo.MinBulkCraft && task.amount <= craftInfo.MaxBulkCraft && task.amount > 0)
                    {
                        var stacks = GetStacks(task.amount * task.blueprint.amountToCreate, task.blueprint.targetItem.stackable);
                        if (!HasPlace(crafter, stacks))
                        {
                            ReturnCraft(task, crafter);
                            return true;
                        }
                        if (bypassCraftLevelRequirement || CanInstantCraft(crafter))
                        {
                            if (!task.blueprint.name.Contains("(Clone)"))
                                task.blueprint = UnityEngine.Object.Instantiate(task.blueprint);
                            task.blueprint.amountToCreate *= task.amount;
                            crafter.inventory.crafting.FinishCrafting(task);
                            task.cancelled = true;
                            return true;
                        }
                    }
                }
            }

            if (!task.blueprint.name.Contains("(Clone)"))
                task.blueprint = UnityEngine.Object.Instantiate(task.blueprint);

            task.blueprint.time = craftingTime;

            return null;
        }
        private List<int> GetStacks(int amount, int maxStack)
        {
            List<int> stacks = new();
            while (amount > maxStack && amount > 0)
            {
                amount -= maxStack;
                stacks.Add(maxStack);
            }
            if (amount > 0)
            {
                stacks.Add(amount);
            }
            return stacks;
        }
        private bool HasPlace(BasePlayer crafter, List<int> stacks)
        {
            if (!config.settings.craftingDetails.slots)
            {
                return true;
            }
            var capacity = crafter.inventory.containerMain.capacity + crafter.inventory.containerBelt.capacity;
            var taken = crafter.inventory.containerMain.itemList.Count + crafter.inventory.containerBelt.itemList.Count;
            var slots = capacity - taken;
            if (slots - stacks.Count < 0)
            {
                return false;
            }
            return slots > 0;
        }
        private bool CanInstantCraftNoLevelRequirement(BasePlayer crafter)
        {
            return config.settings.craftingDetails.noLevelRequirement && permission.UserHasPermission(crafter.UserIDString, config.settings.craftingDetails.Permission);
        }
        private bool CanInstantCraft(BasePlayer crafter)
        {
            if (config.settings.craftingDetails.usePermission)
            {
                return permission.UserHasPermission(crafter.UserIDString, config.settings.craftingDetails.Permission);
            }
            return true;
        }
        private void ReturnCraft(ItemCraftTask task, BasePlayer crafter)
        {
            task.cancelled = true;
            Message(crafter, "NoSlots");
            foreach (var item in task.takenItems)
            {
                if (item.amount > 0)
                    crafter.GiveItem(item);
            }
        }
        private object OnItemCraftFinished(ItemCraftTask task, Item item, ItemCrafter craft)
        {
            if (task == null) return null;
            var crafter = craft?.owner;
            if (crafter == null || !hasRights(crafter.UserIDString)) return null;
            var bypassLevelRequirement = CanInstantCraftNoLevelRequirement(crafter);
            if (!bypassLevelRequirement && !IsSkillEnabled(Skills.CRAFTING)) return null;
            var pi = GetPlayerInfo(crafter);
            var xpPercentBefore = getExperiencePercent(pi, Skills.CRAFTING);
            if (task.blueprint == null)
            {
                Puts("There is problem obtaining task.blueprint on 'OnItemCraftFinished' hook! This is usually caused by some incompatable plugins.");
                return null;
            }
            var experienceGain = (task.blueprint.time + 0.99f) / config.settings.craftingDetails.time;
            if (experienceGain == 0)
                return null;

            double Level = pi.CRAFTING_LEVEL;
            double Points = pi.CRAFTING_POINTS;
            Points += experienceGain * config.settings.craftingDetails.xp;
            if (Points >= getLevelPoints(Level + 1))
            {
                var levelCap = config.settings.levelCaps.CRAFTING;
                var maxLevel = levelCap > 0 && Level + 1 > levelCap;
                if (!maxLevel)
                {
                    Level = getPointsLevel(Points, Skills.CRAFTING);
                    string format = $"<color={config.settings.colors.CRAFTING}>{_("LevelUpText", crafter.UserIDString)}</color>";
                    string message = string.Format(format, _("CRAFTINGSkill", crafter.UserIDString), Level, Points, getLevelPoints(Level + 1), pi.CRAFTING_LEVEL * Convert.ToDouble(config.settings.craftingDetails.percent));
                    Player.Message(crafter, message, string.IsNullOrEmpty(config.generic.pluginPrefix) ? string.Empty : config.generic.pluginPrefix, config.generic.steamIDIcon);
                    GiveReward(crafter, Skills.CRAFTING, Level);
                    if (config.generic.enableLevelupBroadcast)
                    {
                        foreach (var target in BasePlayer.activePlayerList)
                        {
                            if (target != null && target.userID != crafter.userID && hasRights(target.UserIDString) && GetPlayerInfo(target).ENABLED)
                            {
                                Message(target, "LevelUpTextBroadcast", crafter.displayName, Level, config.settings.colors.CRAFTING, _("CRAFTINGSkill", crafter.UserIDString));
                            }
                        }
                    }
                }
            }
            try
            {
                if (item.info.shortname != "lantern_a" && item.info.shortname != "lantern_b")
                    setPointsAndLevel(pi, Skills.CRAFTING, Points, Level);
            }
            catch { }

            try
            {
                var xpPercentAfter = getExperiencePercent(pi, Skills.CRAFTING);
                if (xpPercentAfter != xpPercentBefore)
                    GUIUpdateSkill(crafter, Skills.CRAFTING);
            }
            catch { }

            if (task.amount > 0) return null;
            if (task.blueprint != null && task.blueprint.name.Contains("(Clone)"))
            {
                var behaviours = task.blueprint.GetComponents<MonoBehaviour>();
                foreach (var behaviour in behaviours)
                {
                    if (behaviour.name.Contains("(Clone)")) UnityEngine.Object.Destroy(behaviour);
                }
            }
            return null;
        }

        #endregion Serverhooks

        #region Commands

        [HookMethod("SendHelpText"), ChatCommand("stathelp")]
        private void SendHelpText(BasePlayer player)
        {
            _sb.Clear();
            _sb.AppendLine("<size=18><color=orange>ZLevels</color></size><size=14><color=#ce422b>REMASTERED</color></size>");
            _sb.AppendLine("/stats - Displays your stats.");
            _sb.AppendLine("/statsui - Enable/Disable stats UI.");
            _sb.AppendLine("/statsonoff - Enable/Disable whole leveling.");
            _sb.AppendLine("/statinfo - Displays information about skills.");
            _sb.AppendLine("/stathelp - Displays the help.");
            //sb.AppendLine("/topskills - Display max levels reached so far.");
            SendReply(player, _sb.ToString());
        }

        private void PointsPerHitCommand(IPlayer user, string command, string[] args)
        {
            if (!user.IsAdmin) return;
            if (args.Length < 2)
            {
                user.Reply("Syntax: zl.pointsperhit skill number");
                user.Reply("Possible skills are: WC, M, S, A, C, *(All skills)");
                _sb.Clear();
                _sb.Append("Current points per hit:");
                foreach (var currSkill in AllSkills)
                {
                    if (!IsSkillEnabled(currSkill)) continue;
                    _sb.Append($" {currSkill} > {pointsPerHitCurrent.Get(currSkill)} |");
                }
                user.Reply(_sb.ToString().TrimEnd('|'));
                return;
            }
            if (!double.TryParse(args[1], out var points) || points < 1)
            {
                user.Reply("Incorrect number.Must be greater than or equal to 1");
                return;
            }

            var skillName = args[0].ToUpper();
            Skills skill;
            if (skillName == "*") skill = Skills.ALL;
            else if (skillName.Equals("C")) skill = Skills.CRAFTING;
            else if (skillName.Equals("WC")) skill = Skills.WOODCUTTING;
            else if (skillName.Equals("M")) skill = Skills.MINING;
            else if (skillName.Equals("A")) skill = Skills.ACQUIRE;
            else if (skillName.Equals("S")) skill = Skills.SKINNING;
            else { user.Reply("Incorrect skill.Possible skills are: WC, M, S, A, C, *(All skills)."); return; }

            if (skill == Skills.ALL)
            {
                foreach (var currSkill in AllSkills)
                {
                    if (!IsSkillEnabled(currSkill)) continue;
                    pointsPerHitCurrent.Set(currSkill, points);
                }
                _sb.Clear();
                _sb.Append("New points per hit:");
                foreach (var currSkill in AllSkills)
                {
                    if (!IsSkillEnabled(currSkill)) continue;
                    _sb.Append($" {currSkill} > {pointsPerHitCurrent.Get(currSkill)} |");
                }
                user.Reply(_sb.ToString().TrimEnd('|'));
            }
            else
            {
                pointsPerHitCurrent.Set(skill, points);
                _sb.Clear();
                _sb.Append("New points per hit:");
                foreach (var currSkill in AllSkills)
                {
                    if (!IsSkillEnabled(currSkill)) continue;
                    _sb.Append($" {currSkill} > {pointsPerHitCurrent.Get(currSkill)} |");
                }
                user.Reply(_sb.ToString().TrimEnd('|'));
            }
        }

        private void PlayerXpmCommand(IPlayer user, string command, string[] args)
        {
            if (!user.IsAdmin) return;
            if (args.Length < 1)
            {
                user.Reply(_("XPM USE 1", user.Id));
                user.Reply(_("XPM USE 2", user.Id));
                return;
            }
            IPlayer target = covalence.Players.FindPlayer(args[0]);
            if (target == null)
            {
                user.Reply(_("PLAYER NOT FOUND", user.Id));
                return;
            }
            if (!data.PlayerInfo.TryGetValue(Convert.ToUInt64(target.Id), out var playerData))
            {
                user.Reply("PlayerData is NULL!");
                return;
            }
            if (args.Length < 2)
            {
                var bonus1 = getXpMulti(playerData, target.Id);
                var baseMultiplier = playerData.XP_MULTIPLIER;
                if (baseMultiplier != bonus1)
                {
                    user.Reply($"Current XP multiplier for player '{target.Name}' is {baseMultiplier}% with vip raising total to {bonus1}%");
                }
                else user.Reply($"Current XP multiplier for player '{target.Name}' is {baseMultiplier}%");
                return;
            }
            double multiplier = -1;
            if (double.TryParse(args[1], out multiplier))
            {
                if (multiplier <= 0)
                {
                    user.Reply("Incorrect number.Must be greater than 0");
                    return;
                }
            }
            playerData.XP_MULTIPLIER = multiplier;
            var bonus2 = getXpMulti(playerData, target.Id);
            if (multiplier != bonus2)
            {
                user.Reply($"New XP multiplier for player '{target.Name}' is {getXpMulti(playerData, target.Id)}% with vip raising total to {bonus2}%");
            }
            else user.Reply($"New XP multiplier for player '{target.Name}' is {getXpMulti(playerData, target.Id)}%");
        }

        private void InfoCommand(IPlayer user, string command, string[] args)
        {
            if (!user.IsAdmin)
            {
                return;
            }
            if (args.Length < 1)
            {
                if (!GetLookingAtPlayer(user))
                {
                    user.Reply(_("INFO USE", user.Id));
                }
                return;
            }
            IPlayer target = covalence.Players.FindPlayer(args[0]);
            if (target == null)
            {
                user.Reply(_("PLAYER NOT FOUND", user.Id));
                return;
            }
            if (!data.PlayerInfo.TryGetValue(Convert.ToUInt64(target.Id), out var playerData))
            {
                user.Reply("PlayerData is NULL!");
                return;
            }
            PrintInfo(user, target.Id, target.Name, playerData);
        }

        private bool GetLookingAtPlayer(IPlayer user)
        {
            BasePlayer player = user.Object as BasePlayer;
            if (player == null) return false;
            BasePlayer target = RelationshipManager.GetLookingAtPlayer(player);
            if (target == null) return false;
            if (!data.PlayerInfo.TryGetValue(target.userID, out var playerData)) return false;
            PrintInfo(user, target.UserIDString, target.displayName, playerData);
            return true;
        }

        private void PrintInfo(IPlayer user, string targetId, string targetName, PlayerInfo playerData)
        {
            TextTable textTable = new();
            textTable.AddColumn("FieldInfo");
            textTable.AddColumn("Level");
            textTable.AddColumn("Points");
            textTable.AddRow(new string[] { _("ACQUIRESkill", targetId), $"{playerData.ACQUIRE_LEVEL:#0.##}", $"{playerData.ACQUIRE_POINTS:#0.##}" });
            textTable.AddRow(new string[] { _("CRAFTINGSkill", targetId), $"{playerData.CRAFTING_LEVEL:#0.##}", $"{playerData.CRAFTING_POINTS:#0.##}" });
            textTable.AddRow(new string[] { _("MININGSkill", targetId), $"{playerData.MINING_LEVEL:#0.##}", $"{playerData.MINING_POINTS:#0.##}" });
            textTable.AddRow(new string[] { _("SKINNINGSkill", targetId), $"{playerData.SKINNING_LEVEL:#0.##}", $"{playerData.SKINNING_POINTS:#0.##}" });
            textTable.AddRow(new string[] { _("WOODCUTTINGSkill", targetId), $"{playerData.WOODCUTTING_LEVEL:#0.##}", $"{playerData.WOODCUTTING_POINTS:#0.##}" });
            textTable.AddRow(new string[] { _("XPM", targetId), $"{getXpMulti(playerData, targetId):#0.##}%", string.Empty });
            user.Reply($"\n{_("STATS", targetId)}{targetName}\n{textTable}");
        }

        private void ResetCommand(IPlayer user, string command, string[] args)
        {
            if (!user.IsAdmin) return;
            if (args.Length != 1 || args[0] != "true")
            {
                user.Reply(_("RESET USE", user.Id));
                return;
            }
            WipeData();
            SaveData();
            foreach (var player in BasePlayer.activePlayerList)
            {
                DestroyGUI(player);
                CreateGUI(player, GetPlayerInfo(player));
            }
            user.Reply("Userdata was successfully reset to zero");
            Puts("{0} ({1}) reset userdata to zero", user.Name, user.Id);
        }

        private void ZlvlCommand(IPlayer user, string command, string[] args)
        {
            if (!user.IsAdmin) return;

            if (args.Length < 3)
            {
                _sb.Clear();
                _sb.AppendLine("Syntax: zl.lvl name|steamid skill [OPERATOR]NUMBER");
                _sb.AppendLine("Example: zl.lvl Player WC /2 -- Player gets his WC level divided by 2.");
                _sb.AppendLine("Example: zl.lvl * * +3 -- Everyone currently playing in the server gets +3 for all skills.");
                _sb.AppendLine("Example: zl.lvl ** * /2 -- Everyone (including offline players) gets their level divided by 2.");
                _sb.AppendLine("Instead of names you can use wildcard(*): * - affects online players, ** - affects all players");
                _sb.AppendLine("Possible operators: *(XP Modified %), +(Adds level), -(Removes level), /(Divides level)").AppendLine();
                user.Reply(_sb.ToString());
                return;
            }
            var playerName = args[0];
            IPlayer target = covalence.Players.FindPlayer(playerName);

            if (playerName != "*" && playerName != "**" && target == null)
            {
                user.Reply(_("PLAYER NOT FOUND", user.Id));
                return;
            }
            if (playerName != "*" && playerName != "**" && !data.PlayerInfo.ContainsKey(Convert.ToUInt64(target.Id)))
            {
                user.Reply("PlayerData is NULL!");
                return;
            }

            if (target != null || playerName == "*" || playerName == "**")
            {
                var playerMode = 0; // Exact player
                if (playerName == "*")
                    playerMode = 1; // Online players
                else if (playerName == "**")
                    playerMode = 2; // All players
                var skillName = args[1].ToUpper();
                Skills skill;
                if (skillName == "*") skill = Skills.ALL;
                else if (skillName.Equals("C")) skill = Skills.CRAFTING;
                else if (skillName.Equals("WC")) skill = Skills.WOODCUTTING;
                else if (skillName.Equals("M")) skill = Skills.MINING;
                else if (skillName.Equals("A")) skill = Skills.ACQUIRE;
                else if (skillName.Equals("S")) skill = Skills.SKINNING;
                else { user.Reply("Incorrect skill.Possible skills are: WC, M, S, A, C, *(All skills)."); return; }
                var mode = 0; // 0 = SET, 1 = ADD, 2 = SUBTRACT, 3 = multiplier, 4 = divide
                int value;
                bool correct;
                if (args[2][0] == '+')
                {
                    mode = 1;
                    correct = int.TryParse(args[2].Replace("+", string.Empty), out value);
                }
                else if (args[2][0] == '-')
                {
                    mode = 2;
                    correct = int.TryParse(args[2].Replace("-", string.Empty), out value);
                }
                else if (args[2][0] == '*')
                {
                    mode = 3;
                    correct = int.TryParse(args[2].Replace("*", string.Empty), out value);
                }
                else if (args[2][0] == '/')
                {
                    mode = 4;
                    correct = int.TryParse(args[2].Replace("/", string.Empty), out value);
                }
                else
                {
                    correct = int.TryParse(args[2], out value);
                }
                if (correct)
                {
                    if (mode == 3) // Change XP Multiplier.{
                        if (skill != Skills.ALL)
                        {
                            user.Reply("XPMultiplier is changeable for all skills! Use * instead of " + skill + ".");
                            return;
                        }
                        if (playerMode == 1)
                        {
                            foreach (var currPlayer in BasePlayer.activePlayerList)
                                editMultiplierForPlayer(value, currPlayer.userID);
                        }
                        else if (playerMode == 2)
                            editMultiplierForPlayer(value);
                        else if (target != null)
                            editMultiplierForPlayer(value, Convert.ToUInt64(target.Id));

                        var whom = playerMode == 1 ? "ALL ONLINE PLAYERS" : playerMode == 2 ? "ALL PLAYERS" : target.Name;
                        user.Reply($"XP rates has changed to {value}% of normal XP for {whom}");
                        return;
                    }
                    if (playerMode == 1)
                    {
                        foreach (var connPlayer in covalence.Players.Connected)
                        {
                            adminModifyPlayerStats(user, skill, value, mode, connPlayer);
                        }
                    }
                    else if (playerMode == 2)
                    {
                        foreach (var other in covalence.Players.All)
                        {
                            if (data.PlayerInfo.ContainsKey(Convert.ToUInt64(other.Id)))
                            {
                                adminModifyPlayerStats(user, skill, value, mode, other);
                            }
                        }
                    }
                    else
                    {
                        adminModifyPlayerStats(user, skill, value, mode, target);
                    }
                }
            }
        }

        private void CheckCommand(IPlayer user, string command, string[] args)
        {
            if (!user.IsAdmin) return;

            int count = 0;
            var pi = CreatePlayerInfo();

            foreach (var info in data.PlayerInfo)
            {
                if (info.Value.IsDefault(pi))
                {
                    count++;
                }
            }

            user.Reply($"{count} / {data.PlayerInfo.Count} entries in datafile can be removed");
        }

        private void CleanCommand(IPlayer user, string command, string[] args)
        {
            if (!user.IsAdmin) return;

            int count = data.PlayerInfo.Count;
            int cleaned = Clean();

            user.Reply($"{cleaned} / {count} entries in datafile have been removed");
            SaveData();
        }

        private int Clean()
        {
            int count = 0;

            if (data == null)
            {
                return count;
            }

            var pi = CreatePlayerInfo();

            foreach (var info in data.PlayerInfo.ToList())
            {
                if (info.Value.IsDefault(pi))
                {
                    count++;
                    data.PlayerInfo.Remove(info.Key);
                }
            }

            return count;
        }

        private void PenaltyCommand(IPlayer user, string command, string[] args)
        {
            if (!user.IsAdmin) return;

            if (args.Length == 1 && args[0] == "status")
            {
                user.Reply(config.generic.penaltyOnDeath ? "Penalty is currently enabled." : "Penalty is currently disabled.");
                return;
            }

            if (args.Length == 0) config.generic.penaltyOnDeath = !config.generic.penaltyOnDeath;
            else config.generic.penaltyOnSuicide = !config.generic.penaltyOnSuicide;

            if (config.generic.penaltyOnDeath || config.generic.penaltyOnSuicide)
            {
                Subscribe(nameof(OnEntityDeath));
                user.Reply("Penalty is now enabled.");
            }
            else
            {
                Unsubscribe(nameof(OnEntityDeath));
                user.Reply("Penalty is now disabled.");
            }

            SaveConfig();
        }

        [ChatCommand("stats")]
        private void StatsCommand(BasePlayer player, string command, string[] args)
        {
            if (!hasRights(player.UserIDString))
            {
                Message(player, "NoPermission");
                return;
            }
            _sb.Clear();
            _sb.AppendLine("<size=18><color=orange>ZLevels</color></size><size=14><color=#ce422b>REMASTERED</color></size>");
            foreach (Skills skill in AllSkills) _sb.Append(getStatPrint(player, skill));
            var pi = GetPlayerInfo(player.userID);
            var alive = ReadableTimeSpan(DateTime.UtcNow - ToDateTimeFromEpoch(pi.LAST_DEATH));
            _sb.AppendLine().AppendLine($"Time alive: {alive}");
            _sb.AppendLine($"XP rates for you are {getXpMulti(pi, player.UserIDString)}
// ... [Code preview truncated due to length. Full source in attached file] ...

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