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

FREE PlayerHealth : 1.0.7 1.0.7

Нет прав для скачивания
C#:
using System;
using System.Collections.Generic;
using HarmonyLib;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Plugins.PlayerHealthMethods;
using UnityEngine;
/*1.0.7
 * Added "Revert to vanilla in SurvivalArena" to config
 */
/*1.0.6
 * Added "Revert to vanilla in RaidableBases" and "Revert to vanilla in AbandonedBases" to config
*/
namespace Oxide.Plugins {
    [Info("Player Health", "beee", "1.0.7")]
    [Description("Permission based max health")]
    class PlayerHealth : RustPlugin {
        private const string PREFIX_LONG = "playerhealth";
        [PluginReference]
        private Plugin RaidableBases, AbandonedBases, SurvivalArena;
        private PluginConfig _config;
#region Load/Unload Hooks
        private void Init() {
            UnsubscribeHooks();
        }
        private void OnServerInitialized() {
            RegisterPermissions();
            foreach (var player in BasePlayer.allPlayerList) ValidateMaxHealth(player);
        }
        private void Unload() {
            foreach (var player in BasePlayer.allPlayerList) SetMaxHealth(player);
        }
        private void UnsubscribeHooks() {
            if (!_config.GeneralSettings.RevertInRaidableBases) {
                Unsubscribe(nameof(OnPlayerEnteredRaidableBase));
                Unsubscribe(nameof(OnPlayerExitedRaidableBase));
            }
            if (!_config.GeneralSettings.RevertInAbandonedBases) {
                Unsubscribe(nameof(OnPlayerEnteredAbandonedBase));
                Unsubscribe(nameof(OnPlayerExitAbandonedBase));
            }
            if (!_config.GeneralSettings.RevertInSurvivalArena) {
                Unsubscribe(nameof(OnEventJoined));
                Unsubscribe(nameof(OnEventLeave));
            }
        }
#endregion
#region Hooks
        private void OnPlayerConnected(BasePlayer player) => OnPlayerRespawned(player);
        private void OnPlayerRespawned(BasePlayer player) {
            ValidateMaxHealth(player);
        }
        void OnUserPermissionGranted(string id, string permName) => OnUserPermissionRevoked(id, permName);
        void OnUserPermissionRevoked(string id, string permName) {
            if(permName.StartsWith(PREFIX_LONG)) {
                if (!ulong.TryParse(id, out ulong userId)) return;
                var player = BasePlayer.FindByID(userId);
                ValidateMaxHealth(player);
            }
        }
        private void OnPlayerAddModifiers(BasePlayer player, Item item, ItemModConsumable consumable) {
            //player.SendNetworkUpdate(); //Temp fix for hp bar not updating when consuming max health tea
            NextTick(() => ValidateMaxHealthModifiers(player));
            var configPermSettings = GetPermissionBasedMaxHealth(player);
            if (configPermSettings == null || !configPermSettings.EnhancedHealing) return;
            ApplyBonusHealing(player, consumable);
        }
        private void OnHealingItemUse(MedicalTool medicalTool, BasePlayer player) {
            var configPermSettings = GetPermissionBasedMaxHealth(player);
            if (configPermSettings == null || !configPermSettings.EnhancedHealing) return;
            ItemModConsumable consumable = medicalTool.GetOwnerItemDefinition().GetComponent<ItemModConsumable>();
            if(!consumable) return;
            ApplyBonusHealing(player, consumable);
        }
#endregion
#region Functions
        private void RegisterPermissions() {
            if (_config == null || _config.Permissions == null) return;
            foreach(var perm in _config.Permissions) permission.RegisterPermission($"{PREFIX_LONG}.{perm.Key.ToLower()}", this);
        }
        private Config_PermissionSettings GetPermissionBasedMaxHealth(BasePlayer player) {
            for (int i = _config.Permissions.Count - 1; i >= 0; i--) {
                if (permission.UserHasPermission(player.UserIDString, $"{PREFIX_LONG}.{_config.Permissions.ElementAt(i).Key}")) {
                    return _config.Permissions.ElementAt(i).Value;
                }
            }
            return null;
        }
        private bool IsCustomMaxHealthProhibited(BasePlayer player) {
            return CheckIsRaidTerritory(player.transform.position) || CheckIsInEvent(player);
        }
        private void ValidateMaxHealth(BasePlayer player) {
            if (player == null) return;
            // Check if any third-party plugin prohibits custom max health
            if (IsCustomMaxHealthProhibited(player)) {
                SetMaxHealth(player, null);
                return;
            }
            var configPermSettings = GetPermissionBasedMaxHealth(player);
            SetMaxHealth(player, configPermSettings);
        }
        private void SetMaxHealth(BasePlayer player, Config_PermissionSettings configPermSettings = null, float startHealthRatio = 0.6f) {
            float newMaxHealthOverride = 0;
            float newMaxHealth = player.StartMaxHealth();
            float newStartHealth = newMaxHealth * startHealthRatio;
            if (configPermSettings != null) {
                newMaxHealthOverride = configPermSettings.MaxHealth;
                newMaxHealth = configPermSettings.MaxHealth;
                newStartHealth = newMaxHealth * (configPermSettings.StartHealthPercent / 100f);
            }
            if (player._maxHealth == newMaxHealth) return;
            player._maxHealth = newMaxHealth;
            player.maxHealthOverride = newMaxHealthOverride > 0 ? GetMaxHealthWithModifier(player) : 0;
            player._health = Mathf.Clamp(newStartHealth, 1, newMaxHealth);
            player.metabolism.pending_health.max = newMaxHealth;
            player.SendNetworkUpdate();
        }
        public static void ValidateMaxHealthModifiers(BasePlayer player) {
            if (player == null || player.maxHealthOverride <= 0) return;
            float maxHealthWithModifier = GetMaxHealthWithModifier(player);
            if(player.maxHealthOverride == maxHealthWithModifier) return;
            player.maxHealthOverride = GetMaxHealthWithModifier(player);
            if (player._health > player.maxHealthOverride) player._health = player.maxHealthOverride;
            player.SendNetworkUpdate();
        }
        private void ApplyBonusHealing(BasePlayer player, ItemModConsumable consumable) {
            if(player.maxHealthOverride <= 0) return;
            float bonusRatio = player._maxHealth / player.StartMaxHealth() - 1f;
            if(bonusRatio <= 0) return;
            foreach (ItemModConsumable.ConsumableEffect effect in consumable.effects) {
                switch (effect.type) {
                    case(MetabolismAttribute.Type.Health) : player.health += effect.amount * bonusRatio;
                    break;
                    case(MetabolismAttribute.Type.HealthOverTime) : player.metabolism.ApplyChange(effect.type, effect.amount * bonusRatio, effect.time);
                    break;
                }
            }
        }
        private static float GetMaxHealthWithModifier(BasePlayer player) => player._maxHealth * (float) (1.0 + (player.modifiers != null ? (double) player.modifiers.GetValue(Modifier.ModifierType.Max_Health) : 0.0));
#endregion
#region Config
        private class PluginConfig {
            [JsonProperty(Order = 1000)]
            public Oxide.Core.VersionNumber Version;
            [JsonProperty("Permissions")]
            public Dictionary<string, Config_PermissionSettings> Permissions {
                get;
                set;
            }
            [JsonProperty("General Settings")]
            public Config_GeneralSettings GeneralSettings {
                get;
                set;
            }
            = new();
        }
        private class Config_PermissionSettings {
            [JsonProperty("Max Health")]
            public float MaxHealth {
                get;
                set;
            }
            [JsonProperty("Start health %")]
            public float StartHealthPercent {
                get;
                set;
            }
            = 60;
            [JsonProperty("Healing items to match max health")]
            public bool EnhancedHealing {
                get;
                set;
            }
            = true;
        }
        private class Config_GeneralSettings {
            [JsonProperty("Revert to vanilla in RaidableBases")]
            public bool RevertInRaidableBases {
                get;
                set;
            }
            [JsonProperty("Revert to vanilla in AbandonedBases")]
            public bool RevertInAbandonedBases {
                get;
                set;
            }
            [JsonProperty("Revert to vanilla in SurvivalArena")]
            public bool RevertInSurvivalArena {
                get;
                set;
            }
        }
        private PluginConfig GetDefaultConfig() {
            PluginConfig result = new PluginConfig {
                Version = Version, Permissions = new Dictionary<string, Config_PermissionSettings> {
                    ["tier1"]
                    = new Config_PermissionSettings() {
                        MaxHealth = 150
                    }
                    , ["tier2"] = new Config_PermissionSettings() {
                        MaxHealth = 200
                    }
                    , ["tier3"] = new Config_PermissionSettings() {
                        MaxHealth = 300
                    }
                }
            }
            ;
            return result;
        }
        private void CheckForConfigUpdates() {
            bool changes = false;
            if (_config == null || _config.Permissions == null) {
                PluginConfig tmpDefaultConfig = GetDefaultConfig();
                _config = tmpDefaultConfig;
                changes = true;
            }
            if(_config.Version != Version) changes = true;
            if (changes) {
                _config.Version = Version;
                PrintWarning("Config updated");
                SaveConfig();
            }
        }
        protected override void LoadDefaultConfig() => _config = GetDefaultConfig();
        protected override void LoadConfig() {
            base.LoadConfig();
            _config = Config.ReadObject<PluginConfig>();
            CheckForConfigUpdates();
        }
        protected override void SaveConfig() => Config.WriteObject(_config);
#endregion
#region Harmony
        [AutoPatch]
        [HarmonyPatch(typeof(BaseModifiers<BasePlayer>), "Remove")]
        internal class BaseModifiers_Remove {
            static void Postfix(BasePlayer ___owner, Modifier toRemove) {
                if (toRemove.Type == Modifier.ModifierType.Max_Health) PlayerHealth.ValidateMaxHealthModifiers(___owner);
            }
        }
#endregion
#region Third Party Plugin Support
        //Copied from NTeleportation
        private bool CheckIsRaidTerritory(Vector3 worldPosition) {
            if (_config.GeneralSettings.RevertInAbandonedBases && AbandonedBases?.Call("EventTerritory", worldPosition) is true) return true;
            if (_config.GeneralSettings.RevertInRaidableBases && RaidableBases?.Call("EventTerritory", worldPosition) is true) return true;
            return false;
        }
        private bool CheckIsInEvent(BasePlayer player) {
            if (_config.GeneralSettings.RevertInSurvivalArena && SurvivalArena?.Call("IsEventPlayer", player) is true) return true;
            return false;
        }
        private void OnPlayerEnteredRaidableBase(BasePlayer player, Vector3 raidPosition, bool allowPVP) => SetMaxHealth(player, null, 1f);
        private void OnPlayerExitedRaidableBase(BasePlayer player, Vector3 raidPosition, bool allowPVP) => ValidateMaxHealth(player);
        private void OnPlayerEnteredAbandonedBase(BasePlayer player, Vector3 center, float radius, bool AllowPVP, List<BasePlayer> intruders, List<ulong> intruderIds, List<BaseEntity> entities, List<BuildingPrivlidge> privs, bool canDropBackpack, bool automatedEvent, bool attackEvent, Guid guid) => SetMaxHealth(player, null, 1f);
        private void OnPlayerExitAbandonedBase(BasePlayer player, Vector3 center, float radius, bool AllowPVP, List<BasePlayer> intruders, List<ulong> intruderIds, List<BaseEntity> entities, List<BuildingPrivlidge> privs, bool canDropBackpack, bool automatedEvent, bool attackEvent, Guid guid) => ValidateMaxHealth(player);
        private void OnEventJoined(BasePlayer player, string pluginName) {
            if(_config.GeneralSettings.RevertInSurvivalArena && pluginName == nameof(SurvivalArena)) SetMaxHealth(player, null, 1f);
        }
        private void OnEventLeave(BasePlayer player, string pluginName) {
            if(_config.GeneralSettings.RevertInSurvivalArena && pluginName == nameof(SurvivalArena)) NextTick(() => ValidateMaxHealth(player));
        }
#endregion
    }
}
#region Extension Methods
namespace Oxide.Plugins.PlayerHealthMethods {
    public static class ExtensionMethods {
        public static T ElementAt<T>(this IEnumerable<T> a, int b) {
            using (var c = a.GetEnumerator()) {
                while (c.MoveNext()) {
                    if (b == 0) {
                        return c.Current;
                    }
                    b--;
                }
            }
            return default(T);
        }
    }
}
#endregion

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