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

FREE BloodBags : 2.3.0 2.3.0

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Network;
using Newtonsoft.Json;
using ProtoBuf;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
/*
 * Rewritten from scratch and maintained to present by VisEntities
 * Originally created by Default, up to version 1.8.0
 */
namespace Oxide.Plugins {
    [Info("Blood Bags", "VisEntities", "2.3.0")]
    [Description("Craft and use blood bags to restore health, stop bleeding, boost hydration, and more.")]
    public class BloodBags : RustPlugin {
#region Fields
        private static BloodBags _plugin;
        private static Configuration _config;
        private BloodUsageListenerManager _manager;
        private List<Timer> _activeCraftingTimers = new List<Timer>();
        private const int ITEM_ID_BLOOD = 1776460938;
        private const string ITEM_SHORTNAME_BLOOD = "blood";
        private const string FX_DRINK = "assets/bundled/prefabs/fx/gestures/drink_generic.prefab";
        private const string FX_TAKE_DAMAGE = "assets/bundled/prefabs/fx/takedamage_generic.prefab";
#endregion Fields
#region Configuration
        private class Configuration {
            [JsonProperty("Version")]
            public string Version {
                get;
                set;
            }
            [JsonProperty("Instant Health Increase")]
            public float InstantHealthIncrease {
                get;
                set;
            }
            [JsonProperty("Health Increase Over Time")]
            public float HealthIncreaseOverTime {
                get;
                set;
            }
            [JsonProperty("Calorie Boost")]
            public float CalorieBoost {
                get;
                set;
            }
            [JsonProperty("Hydration Boost")]
            public float HydrationBoost {
                get;
                set;
            }
            [JsonProperty("Stop Bleeding")]
            public bool StopBleeding {
                get;
                set;
            }
            [JsonProperty("Temperature Target")]
            public float TemperatureTarget {
                get;
                set;
            }
            [JsonProperty("Radiation Poisoning Reduction")]
            public float RadiationPoisoningReduction {
                get;
                set;
            }
            [JsonProperty("Amount To Consume")]
            public int AmountToConsume {
                get;
                set;
            }
            [JsonProperty("Crafting")]
            public CraftingConfig Crafting {
                get;
                set;
            }
        }
        private class CraftingConfig {
            [JsonProperty("Command")]
            public string Command {
                get;
                set;
            }
            [JsonProperty("Workbench Level Required")]
            public float WorkbenchLevelRequired {
                get;
                set;
            }
            [JsonProperty("Health Sacrifice Amount")]
            public float HealthSacrificeAmount {
                get;
                set;
            }
            [JsonProperty("Crafting Time Seconds")]
            public float CraftingTimeSeconds {
                get;
                set;
            }
            [JsonProperty("Crafting Amount")]
            public int CraftingAmount {
                get;
                set;
            }
            [JsonProperty("Ingredients")]
            public List<ItemInfo> Ingredients {
                get;
                set;
            }
        }
        public class ItemInfo {
            [JsonProperty("Shortname")]
            public string Shortname {
                get;
                set;
            }
            [JsonProperty("Amount")]
            public int Amount {
                get;
                set;
            }
            [JsonIgnore]
            private bool _validated;
            [JsonIgnore]
            private ItemDefinition _itemDefinition;
            [JsonIgnore]
            public ItemDefinition ItemDefinition {
                get {
                    if (!_validated) {
                        ItemDefinition matchedItemDefinition = ItemManager.FindItemDefinition(Shortname);
                        if (matchedItemDefinition != null) _itemDefinition = matchedItemDefinition;
                        else return null;
                        _validated = true;
                    }
                    return _itemDefinition;
                }
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            _config = Config.ReadObject<Configuration>();
            if (string.Compare(_config.Version, Version.ToString()) < 0) UpdateConfig();
            SaveConfig();
        }
        protected override void LoadDefaultConfig() {
            _config = GetDefaultConfig();
        }
        protected override void SaveConfig() {
            Config.WriteObject(_config, true);
        }
        private void UpdateConfig() {
            PrintWarning("Config changes detected! Updating...");
            Configuration defaultConfig = GetDefaultConfig();
            if (string.Compare(_config.Version, "1.0.0") < 0) _config = defaultConfig;
            if (string.Compare(_config.Version, "2.1.0") < 0) {
                _config.Crafting.HealthSacrificeAmount = defaultConfig.Crafting.HealthSacrificeAmount;
            }
            if (string.Compare(_config.Version, "2.2.0") < 0) {
                _config.InstantHealthIncrease = defaultConfig.InstantHealthIncrease;
                _config.HealthIncreaseOverTime = defaultConfig.HealthIncreaseOverTime;
            }
            PrintWarning("Config update complete! Updated from version " + _config.Version + " to " + Version.ToString());
            _config.Version = Version.ToString();
        }
        private Configuration GetDefaultConfig() {
            return new Configuration {
                Version = Version.ToString(), InstantHealthIncrease = 20f, HealthIncreaseOverTime = 20f, CalorieBoost = 100f, HydrationBoost = 50f, StopBleeding = true, TemperatureTarget = 25f, RadiationPoisoningReduction = 25f, AmountToConsume = 2, Crafting = new CraftingConfig {
                    Command = "craftblood", WorkbenchLevelRequired = 1, HealthSacrificeAmount = 15f, CraftingTimeSeconds = 10f, Ingredients = new List<ItemInfo> {
                        new ItemInfo {
                            Shortname = "cloth", Amount = 20
                        }
                        , new ItemInfo {
                            Shortname = "ducttape", Amount = 1
                        }
                        , new ItemInfo {
                            Shortname = "skull.human", Amount = 1
                        }
                    }
                }
            }
            ;
        }
#endregion Configuration
#region Oxide Hooks
        private void Init() {
            _plugin = this;
            _manager = new BloodUsageListenerManager();
            PermissionUtil.RegisterPermissions();
            cmd.AddChatCommand(_config.Crafting.Command, this, nameof(cmdCraftBloodBag));
        }
        private void Unload() {
            foreach (Timer timer in _activeCraftingTimers) {
                if (timer != null) timer.Destroy();
            }
            _manager.Unload();
            _config = null;
            _plugin = null;
        }
        private void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem) {
            if (player == null || !PermissionUtil.VerifyHasPermission(player)) return;
            bool isOldItemBloodBag = oldItem != null && oldItem.info.shortname == ITEM_SHORTNAME_BLOOD;
            bool isNewItemBloodBag = newItem != null && newItem.info.shortname == ITEM_SHORTNAME_BLOOD;
            if (isOldItemBloodBag && isNewItemBloodBag) return;
            if (isNewItemBloodBag) {
                BloodUsageListenerComponent component = _manager.GetBloodUsageListener(player);
                if (component == null) {
                    _manager.AddBloodUsageListener(player, newItem);
                    SendGameTip(player, lang.GetMessage(Lang.UseInstruction, this, player.UserIDString), 5f);
                }
            }
            else if (isOldItemBloodBag && !isNewItemBloodBag) {
                BloodUsageListenerComponent component = _manager.GetBloodUsageListener(player);
                if (component != null) {
                    _manager.DestroyBloodUsageListener(player);
                }
            }
        }
#endregion Oxide Hooks
#region Blood Usage Listener Component
        public class BloodUsageListenerManager {
            private Dictionary<BasePlayer, BloodUsageListenerComponent> _bloodUsageListeners = new Dictionary<BasePlayer, BloodUsageListenerComponent>();
            public bool AddBloodUsageListener(BasePlayer player, Item bloodItem) {
                if (_bloodUsageListeners.ContainsKey(player)) return false;
                BloodUsageListenerComponent component = BloodUsageListenerComponent.InstallComponent(player, this, bloodItem);
                _bloodUsageListeners[player] = component;
                return true;
            }
            public void HandleBloodUsageListenerDestroyed(BasePlayer player) {
                if (_bloodUsageListeners.ContainsKey(player)) _bloodUsageListeners.Remove(player);
            }
            public void Unload() {
                // Convert to an array to avoid 'InvalidOperationException' due to modifying the collection during iteration.This creates a snapshot of the collection.foreach (BloodUsageListenerComponent component in _bloodUsageListeners.Values.ToArray())
                {
                    if (component != null) component.DestroyComponent();
                }
            }
            public void DestroyBloodUsageListener(BasePlayer player) {
                if (_bloodUsageListeners.TryGetValue(player, out BloodUsageListenerComponent component) && component != null) component.DestroyComponent();
            }
            public BloodUsageListenerComponent GetBloodUsageListener(BasePlayer player) {
                if (_bloodUsageListeners.TryGetValue(player, out BloodUsageListenerComponent component)) return component;
                return null;
            }
            public bool BloodUsageListenerCurrentlyActive(BasePlayer player) {
                return _bloodUsageListeners.ContainsKey(player);
            }
        }
        public class BloodUsageListenerComponent : FacepunchBehaviour {
#region Fields
            public BasePlayer Player {
                get;
                set;
            }
            private BloodUsageListenerManager _manager;
            private InputState _playerInput;
            private Item _bloodItem;
            private bool _useButtonPressed = false;
#endregion Fields
#region Component Management
            public static BloodUsageListenerComponent InstallComponent(BasePlayer player, BloodUsageListenerManager manager, Item bloodItem) {
                BloodUsageListenerComponent component = player.gameObject.AddComponent<BloodUsageListenerComponent>();
                component.InitializeComponent(manager, bloodItem);
                return component;
            }
            public BloodUsageListenerComponent InitializeComponent(BloodUsageListenerManager manager, Item bloodItem) {
                Player = GetComponent<BasePlayer>();
                _manager = manager;
                _bloodItem = bloodItem;
                _playerInput = Player.serverInput;
                return this;
            }
            public static BloodUsageListenerComponent GetComponent(BasePlayer player) {
                return player.gameObject.GetComponent<BloodUsageListenerComponent>();
            }
            public void DestroyComponent() {
                DestroyImmediate(this);
            }
#endregion Component Management
#region Component Lifecycle
            private void Update() {
                if (_bloodItem != null && _playerInput.WasJustPressed(BUTTON.USE) && !_useButtonPressed) {
                    int amount = GetItemAmount(ITEM_ID_BLOOD, Player.inventory.containerBelt);
                    if (amount < _config.AmountToConsume) {
                        _plugin.SendReplyToPlayer(Player, Lang.NotEnoughBloodBags, _config.AmountToConsume);
                    }
                    else {
                        ConsumeBlood();
                    }
                    _useButtonPressed = true;
                }
                else if (_playerInput.WasJustReleased(BUTTON.USE)) {
                    _useButtonPressed = false;
                }
            }
            private void OnDestroy() {
                _manager.HandleBloodUsageListenerDestroyed(Player);
            }
#endregion Component Lifecycle
#region Consuming
            private void ConsumeBlood() {
                float healthIncrease = _config.InstantHealthIncrease;
                Player.Heal(healthIncrease);
                Player.metabolism.ApplyChange(MetabolismAttribute.Type.HealthOverTime, _config.HealthIncreaseOverTime, 1f);
                float calorieBoost = _config.CalorieBoost;
                Player.metabolism.calories.Add(calorieBoost);
                float hydrationBoost = _config.HydrationBoost;
                Player.metabolism.hydration.Add(hydrationBoost);
                if (_config.StopBleeding) Player.metabolism.bleeding.value = 0f;
                float targetTemperature = _config.TemperatureTarget;
                Player.metabolism.temperature.value = Mathf.Lerp(Player.metabolism.temperature.value, targetTemperature, 0.5f);
                float radiationReduction = _config.RadiationPoisoningReduction;
                Player.metabolism.radiation_poison.Subtract(radiationReduction);
                TakeItem(Player, ITEM_ID_BLOOD, _config.AmountToConsume, Player.inventory.containerBelt);
                RunEffect(FX_DRINK, Player, boneId : 698017942);
            }
#endregion Consuming
        }
#endregion Blood Usage Listener Component
#region Utility Classes
        private static class PermissionUtil {
            public const string USE = "bloodbags.use";
            public static void RegisterPermissions() {
                _plugin.permission.RegisterPermission(USE, _plugin);
            }
            public static bool VerifyHasPermission(BasePlayer player, string permissionName = USE) {
                return _plugin.permission.UserHasPermission(player.UserIDString, permissionName);
            }
        }
#endregion Utility Classes
#region Helper Functions
        private void SendGameTip(BasePlayer player, string message, float durationSeconds, params object[] args) {
            message = string.Format(message, args);
            player.SendConsoleCommand("gametip.showgametip", message);
            timer.Once(durationSeconds, () => {
                if (player != null) player.SendConsoleCommand("gametip.hidegametip");
            }
            );
        }
        private static void RunEffect(string prefab, BaseEntity entity, uint boneId = 0, Vector3 localPosition = default(Vector3), Vector3 localDirection = default(Vector3), Connection effectRecipient = null, bool sendToAll = false) {
            Effect.server.Run(prefab, entity, boneId, localPosition, localDirection, effectRecipient, sendToAll);
        }
        public static int GetItemAmount(int itemId, ItemContainer container) {
            return container.GetAmount(itemId, true);
        }
        public static void GiveItem(BasePlayer player, int itemId, int amount, ItemContainer container) {
            container.GiveItem(ItemManager.CreateByItemID(itemId, amount));
            player.Command("note.inv", itemId, amount);
        }
        public static int TakeItem(BasePlayer player, int itemId, int amount, ItemContainer container) {
            int amountTaken = container.Take(null, itemId, amount);
            player.Command("note.inv", itemId, -amountTaken);
            return amountTaken;
        }
#endregion Helper Functions
#region Commands
        private void cmdCraftBloodBag(BasePlayer player, string command, string[] args) {
            if (!PermissionUtil.VerifyHasPermission(player)) {
                SendReplyToPlayer(player, Lang.NoPermission);
                return;
            }
            string requiredWorkbench = $"Workbench{_config.Crafting.WorkbenchLevelRequired}";
            if (!player.HasPlayerFlag((BasePlayer.PlayerFlags)Enum.Parse(typeof(BasePlayer.PlayerFlags), requiredWorkbench, true))) {
                SendReplyToPlayer(player, Lang.NeedWorkbench, _config.Crafting.WorkbenchLevelRequired);
                return;
            }
            foreach (ItemInfo ingredient in _config.Crafting.Ingredients) {
                int amount = GetItemAmount(ingredient.ItemDefinition.itemid, player.inventory.containerMain);
                if (amount < ingredient.Amount) {
                    SendReplyToPlayer(player, Lang.NotEnoughIngredient, ingredient.Shortname, ingredient.Amount);
                    return;
                }
            }
            if (player.health > _config.Crafting.HealthSacrificeAmount) {
                player.Hurt(_config.Crafting.HealthSacrificeAmount);
            }
            else {
                SendReplyToPlayer(player, Lang.InsufficientHealth, _config.Crafting.HealthSacrificeAmount);
                return;
            }
            foreach (ItemInfo ingredient in _config.Crafting.Ingredients) {
                TakeItem(player, ingredient.ItemDefinition.itemid, ingredient.Amount, player.inventory.containerMain);
            }
            float craftingTimeLeft = _config.Crafting.CraftingTimeSeconds;
            Timer countdownTimer = timer.Repeat(1f, (int)craftingTimeLeft, () => {
                if (player != null && craftingTimeLeft > 0) {
                    SendGameTip(player, lang.GetMessage(Lang.CraftingCountdown, this, player.UserIDString), 1f, craftingTimeLeft);
                    craftingTimeLeft--;
                }
            }
            );
            Timer craftingTimer = timer.Once(_config.Crafting.CraftingTimeSeconds, () => {
                if (player != null) {
                    GiveItem(player, ITEM_ID_BLOOD, _config.Crafting.CraftingAmount, player.inventory.containerMain);
                }
            }
            );
            _activeCraftingTimers.Add(craftingTimer);
            _activeCraftingTimers.Add(countdownTimer);
            RunEffect(FX_TAKE_DAMAGE, player, boneId : 698017942);
            SendReplyToPlayer(player, Lang.CraftingStart, _config.Crafting.CraftingTimeSeconds);
        }
#endregion Commands
#region Localization
        private class Lang {
            public const string NoPermission = "NoPermission";
            public const string NeedWorkbench = "NeedWorkbench";
            public const string NotEnoughIngredient = "NotEnoughIngredient";
            public const string CraftingStart = "CraftingStart";
            public const string NotEnoughBloodBags = "NotEnoughBloodBags";
            public const string InsufficientHealth = "InsufficientHealth";
            public const string UseInstruction = "UseInstruction";
            public const string CraftingCountdown = "CraftingCountdown";
        }
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                [Lang.NoPermission]
                = "You do not have permission to craft this item.", [Lang.NeedWorkbench] = "You need to be near a workbench level <color=#FFD700>{0}</color> to craft this item.", [Lang.NotEnoughIngredient] = "You do not have enough <color=#FFD700>{0}</color>.Required: <color=#FFD700>{1}</color>.", [Lang.CraftingStart] = "Crafting blood bag...Please wait <color=#FFD700>{0}</color> seconds.", [Lang.NotEnoughBloodBags] = "Not enough blood bags.Required: <color=#FFD700>{0}</color>.", [Lang.InsufficientHealth] = "You don't have enough health to craft a blood bag.Required health: <color=#FFD700>{0}</color>.", [Lang.UseInstruction] = "Press <color=#FFD700>use</color> to consume", [Lang.CraftingCountdown] = "Crafting blood bag, <color=#FFD700>{0}</color> seconds remaining",
            }
            , this, "en");
        }
        private void SendReplyToPlayer(BasePlayer player, string messageKey, params object[] args) {
            string message = lang.GetMessage(messageKey, this, player.UserIDString);
            if (args.Length > 0) message = string.Format(message, args);
            SendReply(player, message);
        }
#endregion Localization
    }
}

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