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

FREE CustomizableWeapons : 1.5.21 1.5.21

Нет прав для скачивания
C#:
// Requires: CustomItemDefinitions
// Reference: 0Harmony
#if CARBON
using HarmonyLib;
#else
using HarmonyLib;
#endif
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using UnityEngine;
using System.Reflection.Emit;
using static Oxide.Plugins.CustomItemDefinitions;
namespace Oxide.Plugins {
    [Info("Customizable Weapons", "0xF [dsc.gg/0xf-plugins]", "1.5.21")]
    public class CustomizableWeapons : RustPlugin {
#region Consts
        public const ItemContainer.Flag NoSortify = (ItemContainer.Flag)(8192) | (ItemContainer.Flag)(16384);
        private const ItemDefinition.Flag CUSTOMWEAPON_FLAG = (ItemDefinition.Flag)(32768);
#endregion
#region Variables
        private static CustomizableWeapons Plugin;
#endregion
#region PluginReference
        [PluginReference]
        private Plugin RustTranslationAPI;
#endregion
#region Permissions
        const string giveCommandPerm = "customizableweapons.give";
        const string iconShowPerm = "customizableweapons.icon.show";
        const string iconHidePerm = "customizableweapons.icon.hide";
#endregion
#region Hooks
        private void Init() {
            Plugin = this;
            permission.RegisterPermission(giveCommandPerm, this);
            permission.RegisterPermission(iconShowPerm, this);
            permission.RegisterPermission(iconHidePerm, this);
            LoadConfig();
            if (config.GlobalSettings.GiveOptions.Attachments == null) config.GlobalSettings.GiveOptions.Attachments = ItemManager.itemDictionaryByName.Keys.Where(shortname => shortname.StartsWith("weapon.mod")).ToDictionary(x => x, x => false);
            config.DataItems.Initialize(this);
            RegisterCustomItemDefinitions();
            SaveConfig();
            LoadLang();
            List<WeaponData> weaponDatas = new List<WeaponData>();
            weaponDatas.AddRange(config.DataItems.Default.Values);
            foreach (var list in config.DataItems.Permissions) weaponDatas.AddRange(list.Value.Values);
            weaponDatas.AddRange(config.DataItems.Custom.Values);
            foreach (var _wd in weaponDatas) {
                if (_wd.DamageTypes == null) continue;
                if (_wd.DamageTypeList == null) _wd.DamageTypeList = new Dictionary<string, Rust.DamageTypeList>();
                foreach (var ammo_pair in _wd.DamageTypes) {
                    if (!_wd.DamageTypeList.ContainsKey(ammo_pair.Key)) _wd.DamageTypeList[ammo_pair.Key] = new Rust.DamageTypeList();
                    for (int i = 0; i < DamageTypes.Count; i++) {
                        Rust.DamageType type = DamageTypes[i];
                        string DamageTypeName = DamageTypeNames.Values.ElementAt(i);
                        if (_wd.DamageTypes[ammo_pair.Key].ContainsKey(DamageTypeName)) _wd.DamageTypeList[ammo_pair.Key].Add(type, _wd.DamageTypes[ammo_pair.Key][DamageTypeName]);
                    }
                    ;
                }
            }
            foreach (var perm in config.DataItems.Permissions) permission.RegisterPermission($"customizableweapons.{perm.Key}", this);
        }
        void RegisterCustomItemDefinitions() {
            foreach ((string shortname, CustomItem item) in config.DataItems.Custom) {
                ItemDefinition parentDefinition = ItemManager.FindItemDefinition(item.Shortname);
                if (parentDefinition == null) continue;
                ItemDefinition registeredDefinition = CustomItemDefinitions.RegisterPluginItemDefinition(new CustomItemDefinition {
                    shortname = shortname, parentItemId = parentDefinition.itemid, maxStackSize = 1, flags = CUSTOMWEAPON_FLAG, defaultName = item.Name, defaultDescription = item.Description, defaultSkinId = item.SkinId, itemMods = new List<ItemMod>(parentDefinition.itemMods) {
                        new ItemModEntitySkinner() {
                            skinID = item.SkinId
                        }
                    }
                    .ToArray()
                }
                , this);
            }
        }
        private class ItemModEntitySkinner : ItemMod {
            public override void OnItemCreated(Item item) {
                base.OnItemCreated(item);
                if (skinID > 0) {
                    BaseEntity heldEntity = item.GetHeldEntity();
                    if (heldEntity == null) return;
                    heldEntity.skinID = skinID;
                    heldEntity.SendNetworkUpdate();
                }
            }
            public ulong skinID;
        }
        private void OnServerInitialized() {
            LoadIcon();
            BasePlayer.activePlayerList.ToList().ForEach(player => AddUiIcon(player));
        }
        private void OnUserPermissionGranted(string playerId, string perm) {
            if (perm != iconShowPerm && perm != iconHidePerm) return;
            BasePlayer player = BasePlayer.Find(playerId);
            if (player == null) return;
            OnPermissionsChanged(player);
        }
        private void OnUserPermissionRevoked(string playerId, string perm) {
            if (perm != iconShowPerm && perm != iconHidePerm) return;
            BasePlayer player = BasePlayer.Find(playerId);
            if (player == null) return;
            OnPermissionsChanged(player);
        }
        private void OnGroupPermissionGranted(string groupName, string perm) {
            if (perm != iconShowPerm && perm != iconHidePerm) return;
            BasePlayer.activePlayerList.ToList().ForEach(p => OnPermissionsChanged(p));
        }
        private void OnGroupPermissionRevoked(string groupName, string perm) {
            if (perm != iconShowPerm && perm != iconHidePerm) return;
            BasePlayer.activePlayerList.ToList().ForEach(p => OnPermissionsChanged(p));
        }
        private object OnWeaponReload(BaseProjectile weapon, BasePlayer player) {
            Item item = weapon.GetCachedItem();
            if (item == null) return null;
            WeaponData weaponData;
            if (TryGetWeaponData(player, item, out weaponData)) {
                if (weaponData.FastReload) {
                    if (weapon.TryReloadMagazine(player.inventory, -1)) {
                        weapon.SetHeld(false);
                        weapon.SendChildrenNetworkUpdateImmediate();
                        timer.Once(0.2f, () => {
                            if (player.GetActiveItem().uid == weapon.ownerItemUID) weapon.SetHeld(true);
                        }
                        );
                        return false;
                    }
                }
            }
            return null;
        }
        void OnMagazineReload(BaseProjectile weapon, IAmmoContainer ammoSource, BasePlayer owner) {
            SetupMagizineCapacity(weapon);
        }
        private object OnWeaponModChange(BaseProjectile weapon, BasePlayer player) {
            if (weapon == null) return null;
            var currentCapacity = weapon.primaryMagazine.capacity;
            SetupMagizineCapacity(weapon);
            if (!config.GlobalSettings.DisableUnload) {
                if (currentCapacity == weapon.primaryMagazine.capacity) return false;
                if (weapon.primaryMagazine.contents > 0 && weapon.primaryMagazine.contents > weapon.primaryMagazine.capacity) {
                    Item item = weapon.GetItem();
                    if (item != null && player != null) weapon.UnloadAmmo(item, player);
                }
            }
            return false;
        }
        void OnImpactEffectCreate(HitInfo info) {
            AttackEntity weapon = info.Weapon;
            if (weapon != null) {
                CustomItem customItem;
                Item item = weapon.GetCachedItem();
                if (item == null || item.info) return;
                if (item.info.HasFlag(CUSTOMWEAPON_FLAG) && TryGetCustomItem(item.info, out customItem)) {
                    BaseEntity hitEntity = info.HitEntity;
                    if (hitEntity.IsValid()) {
                        if (customItem.EffectsEntity.ElecticBalls > 0) for (int i = 0; i < customItem.EffectsEntity.ElecticBalls; i++) Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.shock.prefab", info.HitPositionWorld + UnityEngine.Random.insideUnitSphere * 1.5f);
                    }
                    else {
                        if (customItem.EffectsGround.ElecticBall) Effect.server.Run("assets/prefabs/locks/keypad/effects/lock.code.shock.prefab", info.HitPositionWorld);
                    }
                }
            }
        }
        void UpdateItemName(Item item) {
            if (item == null) return;
            NextTick(() => {
                ItemDefinition itemDef = item.info;
                if (itemDef == null) return;
                CustomItem customItem;
                if (itemDef.HasFlag(CUSTOMWEAPON_FLAG) && TryGetCustomItem(itemDef, out customItem)) {
                    var nameLangKey = $"{itemDef.shortname}:Name";
                    var itemName = GetMessage(nameLangKey, item.GetOwnerPlayer()?.UserIDString);
                    if (itemName == nameLangKey) itemName = customItem.Name;
                    SetName(item, customItem, itemName);
                    if (customItem.SkinId != 0) item.skin = customItem.SkinId;
                    item.MarkDirty();
                }
                else {
                    WeaponData weaponData;
                    if (TryGetWeaponData(item.GetOwnerPlayer(), item, out weaponData)) {
                        SetName(item, weaponData);
                        item.MarkDirty();
                    }
                }
            }
            );
        }
        private void OnItemAddedToContainer(ItemContainer container, Item item) {
            if (!container.HasFlag(ItemContainer.Flag.IsPlayer)) return;
            if (container.playerOwner?.inventory?.loot?.IsLooting() != false) return;
            if (!IsWeapon(item)) return;
            UpdateItemName(item);
            NextTick(() => {
                SetupMagizineCapacity(item.GetHeldEntity() as BaseProjectile);
            }
            );
        }
        private void OnRocketLaunched(BasePlayer player, BaseEntity entity) {
            var explosion = entity?.GetComponent<TimedExplosive>();
            if (explosion == null) return;
            Item item = player.GetActiveItem();
            if (item == null) return;
            UpdateHitDamage(explosion.damageTypes, item, player);
        }
        private void OnExplosiveThrown(BasePlayer player, BaseEntity entity) {
            var explosion = entity?.GetComponent<TimedExplosive>();
            if (explosion == null) return;
            Item item = player.GetActiveItem();
            if (item == null) return;
            UpdateHitDamage(explosion.damageTypes, item, player);
        }
        private void OnExplosiveDropped(BasePlayer player, BaseEntity entity) {
            var explosion = entity?.GetComponent<TimedExplosive>();
            if (explosion == null) return;
            Item item = player.GetActiveItem();
            if (item == null) return;
            UpdateHitDamage(explosion.damageTypes, item, player);
        }
        void OnEntityTakeDamage(BaseCombatEntity victim, HitInfo info) {
            BasePlayer initiator = info.Initiator as BasePlayer;
            if (initiator == null) return;
            if (info.Weapon == null) {
                Item activeItem = initiator.GetActiveItem();
                if (activeItem != null) {
                    AttackEntity attackHeldEntity = activeItem.GetHeldEntity() as AttackEntity;
                    if (info.WeaponPrefab != null && attackHeldEntity != null && attackHeldEntity.PrefabName != info.WeaponPrefab.PrefabName) return;
                    info.Weapon = attackHeldEntity;
                }
            }
            if (info.Weapon == null) return;
            var item = info.Weapon.GetCachedItem();
            if (item == null) return;
            var ammoType = string.Empty;
            if (info.Weapon is BaseProjectile) ammoType = (info.Weapon as BaseProjectile).primaryMagazine.ammoType.shortname;
            else if (info.Weapon is BaseMelee) ammoType = "melee";
            else if(info.Weapon is ThrownWeapon) ammoType = "throw";
            else if(info.Weapon is FlameThrower) ammoType = "ammo.lowgrade";
            if (!string.IsNullOrEmpty(ammoType)) {
                float coef = 1f;
                if (DefaultDamageWeapons.TryGetValue(item.info.shortname, out Dictionary<string, Rust.DamageTypeList> damageListByAmmo) && damageListByAmmo.TryGetValue(ammoType, out Rust.DamageTypeList damageList)) coef = info.damageTypes.Total() / damageList.Total();
                UpdateHitDamage(info, initiator, coef);
            }
            else UpdateHitDamage(info, initiator);
            if (info.HitEntity as DecayEntity) {
                if (info.damageTypes.Has(Rust.DamageType.Cold)) info.damageTypes.Scale(Rust.DamageType.Cold, 0f);
                if (info.damageTypes.Has(Rust.DamageType.Poison)) info.damageTypes.Scale(Rust.DamageType.Poison, 0f);
                if (info.damageTypes.Has(Rust.DamageType.Bleeding)) info.damageTypes.Scale(Rust.DamageType.Bleeding, 0f);
                if (info.damageTypes.Has(Rust.DamageType.Hunger)) info.damageTypes.Scale(Rust.DamageType.Hunger, 0f);
                if (info.damageTypes.Has(Rust.DamageType.Thirst)) info.damageTypes.Scale(Rust.DamageType.Thirst, 0f);
                if (info.damageTypes.Has(Rust.DamageType.Suicide)) info.damageTypes.Scale(Rust.DamageType.Suicide, 0f);
                if (info.damageTypes.Has(Rust.DamageType.ElectricShock)) info.damageTypes.Scale(Rust.DamageType.ElectricShock, 0f);
                if (info.damageTypes.Has(Rust.DamageType.Drowned)) info.damageTypes.Scale(Rust.DamageType.Drowned, 0f);
                if (info.damageTypes.Has(Rust.DamageType.Fall)) info.damageTypes.Scale(Rust.DamageType.Fall, 0f);
                if (info.damageTypes.Has(Rust.DamageType.Heat)) info.damageTypes.Scale(Rust.DamageType.Heat, 0f);
            }
            //Effects
            BasePlayer victimPlayer = victim.ToPlayer();
            if (victimPlayer && TryGetWeaponData(initiator as BasePlayer, item, out WeaponData weaponData)) {
                var effects = weaponData.EffectsEntity;
                if (!effects.RadPoison.Equals(0)) {
                    float rad = effects.RadPoison * victimPlayer.RadiationExposureFraction();
                    if (rad > 0) victimPlayer.metabolism.radiation_poison.value = Mathf.Clamp(victimPlayer.metabolism.radiation_poison.value + rad, victimPlayer.metabolism.radiation_poison.min, effects.ValuesSettings.MaxRadPoison);
                }
                if (!effects.Bleeding.Equals(0)) victimPlayer.metabolism.bleeding.value = Mathf.Clamp(victimPlayer.metabolism.bleeding.value + effects.Bleeding, victimPlayer.metabolism.bleeding.min, effects.ValuesSettings.MaxBleading);
                if (!effects.Temperature.Equals(0)) {
                    float temperature = effects.Temperature;
                    if (temperature < 0) {
                        var ColdExposureFraction = (1f - Mathf.Clamp(victimPlayer.baseProtection.amounts[(int)Rust.DamageType.ColdExposure], 0f, 1f));
                        temperature *= ColdExposureFraction;
                    }
                    if (temperature != 0) victimPlayer.metabolism.temperature.value = Mathf.Clamp(victimPlayer.metabolism.temperature.value + temperature, effects.ValuesSettings.MinTemperature, effects.ValuesSettings.MaxTemperature);
                }
                if (!effects.Hunger.Equals(0)) victimPlayer.metabolism.calories.Subtract(effects.Hunger);
                if (!effects.Thirst.Equals(0)) victimPlayer.metabolism.hydration.Subtract(effects.Thirst);
                if (!effects.Wetness.Equals(0)) victimPlayer.metabolism.wetness.value = Mathf.Clamp(victimPlayer.metabolism.wetness.value + effects.Wetness, victimPlayer.metabolism.wetness.min, effects.ValuesSettings.MaxWetness);
            }
        }
        private void OnLoseCondition(Item item, ref float amount) {
            if (!IsWeapon(item)) return;
            BasePlayer owner = item.GetOwnerPlayer();
            if (owner == null) return;
            WeaponData weaponData;
            if (TryGetWeaponData(owner, item, out weaponData)) {
                if (weaponData.Unbreakable) amount = 0f;
                else amount = (amount / (weaponData.Durability / item.info.condition.max)) * (item.maxCondition / item.info.condition.max);
            }
        }
        private void OnPlayerRespawned(BasePlayer player) => AddUiIcon(player);
        private void OnPlayerConnected(BasePlayer player) => AddUiIcon(player);
        private void OnPlayerLootEnd(PlayerLoot playerLoot) {
            var player = (BasePlayer)playerLoot.baseEntity;
            if (playerLoot.entitySource == RelationshipManager.ServerInstance) {
                DestroyUI(player);
                playerLoot.containers.Where(c => c.entityOwner == RelationshipManager.ServerInstance && c.capacity == 0).ToList().ForEach(c => c.Kill());
            }
        }
        void OnLootEntity(BasePlayer player, BaseEntity entity) {
            NextTick(() => {
                foreach (var item in player.inventory.AllItems()) {
                    item.MarkDirty();
                }
            }
            );
        }
        void OnLootEntityEnd(BasePlayer player, BaseCombatEntity entity) {
            NextTick(() => {
                foreach (var item in player.inventory.AllItems()) {
                    item.MarkDirty();
                }
            }
            );
        }
        void OnAmmoSwitch(BaseProjectile baseProjectile, BasePlayer owner) {
            UpdateItemName(baseProjectile.GetCachedItem());
        }
        void Loaded() {
            Harmony.Init(this.Name);
            Harmony.Patch();
        }
        void Unload() {
            Harmony.UnpatchAll();
            BasePlayer.allPlayerList.ToList().ForEach(player => {
                DestroyUI(player);
                DestroyIcon(player);
            }
            );
        }
#endregion
        public static class Harmony {
            private static string Name;
#if CARBON
            private static Harmony _harmony;
#else
            //private static Harmony _harmony;
#endif
            public static void Init(string name) {
                Name = name;
#if CARBON
                Instance = new HarmonyLib.Harmony(name);
#else
                //Instance = HarmonyInstance.Create(name);
#endif
            }
            public static void Patch() {
                //Instance.Patch(AccessTools.Method(typeof(Item), "Save"), postfix: new HarmonyMethod(typeof(Patches), "Item_Save"));
            }
            public static void UnpatchAll() {
                //Instance.UnpatchAll(Name);
            }
        }
        static partial class Patches {
            internal static void Item_Save(Item __instance, ref ProtoBuf.Item __result) {
                if (!SaveRestore.IsSaving && Plugin.IsWeapon(__instance) && __result.streamerName != null && __result.streamerName.StartsWith("\n")) {
                    ItemContainer container = __instance.parent;
                    if (container != null) {
                        BasePlayer player = container.playerOwner;
                        if (player != null && !player.IsNpc && !player.inventory.loot.IsLooting()) __result.name = __result.streamerName;
                    }
                }
            }
        }
#region Commands
        [ConsoleCommand("cw.reload")]
        private void ConsoleCommandReload(ConsoleSystem.Arg arg) {
            if (arg.Player() != null) {
                if (!arg.Player().IsAdmin) {
                    SendReply(arg, "This command is only allowed to administrators");
                    return;
                }
            }
            Server.Command($"o.reload {Name}");
            if (arg.Player() != null) {
                SendReply(arg, "Items successfully reloaded!");
                return;
            }
            Puts("Items successfully reloaded");
        }
        [ConsoleCommand("cw.create")]
        private void ConsoleCommandCreate(ConsoleSystem.Arg arg) {
            if (arg.Player() != null) {
                if (!arg.Player().IsAdmin) {
                    SendReply(arg, "This command is only allowed to administrators");
                    return;
                }
            }
            if (arg.Args.IsNullOrEmpty() || arg.Args?.Count() != 2) {
                if (arg.Player() != null) {
                    SendReply(arg, "Usage: cw.create <new unique shortname> <shortname>");
                    return;
                }
                PrintWarning("Usage: cw.create <new unique shortname> <shortname>");
                return;
            }
            var name = arg.Args[0];
            if (name.Contains(" ")) {
                if(arg.Player() != null) {
                    SendReply(arg, "No spaces are allowed in the unique shortname!");
                    return;
                }
                PrintError("No spaces are allowed in the unique shortname!");
                return;
            }
            var shortname = arg.Args[1];
            if (config.DataItems.CustomFs.ExistsDatafile(name)) {
                if (arg.Player() != null) {
                    SendReply(arg, "A file with this name already exists, delete it or create it under another name.");
                    return;
                }
                PrintWarning("A file with this name already exists, delete it or create it under another name.");
                return;
            }
            if (!config.DataItems.Default.ContainsKey(shortname)) {
                if (arg.Player() != null) {
                    SendReply(arg, $"The shortname '{shortname}' is not suitable, try another one, you can find available shortnames in the 'Default' folder");
                    return;
                }
                PrintWarning($"The shortname '{shortname}' is not suitable, try another one, you can find available shortnames in the 'Default' folder");
                return;
            }
            var defaultItem = config.DataItems.Default[shortname];
            CustomItem newItem = new CustomItem() {
                Shortname = shortname, SkinId = 0, Name = name, Description = "", Unbreakable = defaultItem.Unbreakable, Durability = defaultItem.Durability, MagazineCapacity = defaultItem.MagazineCapacity, DamageTypes = defaultItem.DamageTypes, DamageTypeList = defaultItem.DamageTypeList
            }
            ;
            config.DataItems.CustomFs.WriteObject<CustomItem>(name, newItem);
            config.DataItems.Custom[name] = newItem;
            if (arg.Player() != null) {
                SendReply(arg, $"Custom item with name '{name}' added!");
                return;
            }
            Puts($"Custom item with name '{name}' added!");
        }
        [ConsoleCommand("cw.give")]
        private void ConsoleCommandGive(ConsoleSystem.Arg arg) {
            string nickname = "SERVER";
            BasePlayer player = arg.Player();
            if (player != null) {
                if (!player.IsAdmin && !permission.UserHasPermission(player.UserIDString, giveCommandPerm)) {
                    arg.ReplyWith("You don't have permission to use this command.");
                    return;
                }
                nickname = player.displayName;
            }
            if (arg.Args.IsNullOrEmpty() || arg.Args?.Count() > 2 || arg.Args?.Count() < 1) {
                if (player != null) {
                    arg.ReplyWith("Usage: cw.give <steamid/nickname> <custom item name>");
                    return;
                }
                PrintWarning("Usage: cw.give <steamid/nickname> <custom item name>");
                return;
            }
            BasePlayer playerToGive = arg.Player();
            if (arg.Args?.Count() == 2) {
                playerToGive = BasePlayer.Find(arg.Args[0]);
                if (playerToGive == null) {
                    if (player != null) {
                        arg.ReplyWith($"Player '{arg.Args[0]}' is offline or not exists.");
                        return;
                    }
                    PrintError($"Player '{arg.Args[0]}' is offline or not exists.");
                    return;
                }
            }
            string uniqueShortname = arg.Args?.Last();
            CustomItem customItem;
            if (TryGetCustomItemByKey(uniqueShortname, out customItem)) {
                Item itemToGive = ItemManager.CreateByName(uniqueShortname, 1, customItem.SkinId);
                var nameLangKey = $"{uniqueShortname}:Name";
                var itemName = GetMessage(nameLangKey, playerToGive.UserIDString);
                if (itemName == nameLangKey) itemName = customItem.Name;
                if (itemToGive.contents != null) {
                    foreach (var shortname in config.GlobalSettings.GiveOptions.Attachments.Where(pair => pair.Value).Select(x => x.Key)) {
                        Item item = ItemManager.CreateByName(shortname, 1, 0UL);
                        if (!item.MoveToContainer(itemToGive.contents, -1, true, false, null, true)) item.Remove(0f);
                    }
                }
                var heldEntity = itemToGive.GetHeldEntity();
                if (heldEntity is BaseProjectile) {
                    BaseProjectile weapon = (heldEntity as BaseProjectile);
                    weapon.primaryMagazine.capacity = customItem.MagazineCapacity;
                    weapon.primaryMagazine.definition.builtInSize = customItem.MagazineCapacity;
                    weapon.primaryMagazine.contents = customItem.MagazineCapacity;
                }
                if (heldEntity is ThrownWeapon && itemToGive.MaxStackable() > 1) itemToGive.amount = 100;
                if (!playerToGive.inventory.GiveItem(itemToGive)) {
                    itemToGive.Remove(0f);
                    arg.ReplyWith("Couldn't give item (inventory full?)");
                    PrintWarning($"{nickname}[{(player == null ? "0" : player.UserIDString)}] failed to give a custom item [{uniqueShortname}] to player {playerToGive.displayName}[{(player == null ? "0" : playerToGive.UserIDString)}]!");
                    return;
                }
                SetName(itemToGive, customItem, itemName);
                itemToGive.skin = customItem.SkinId;
                itemToGive.MarkDirty();
                heldEntity.skinID = customItem.SkinId;
                heldEntity.SendNetworkUpdate();
                if (arg.Player() != null) arg.ReplyWith($"Item [{uniqueShortname}] added to {playerToGive.displayName}'s inventory!");
                PrintWarning($"{nickname}[{(player == null ? "0" : player.UserIDString)}] gave {playerToGive.displayName}[{(playerToGive == null ? "0" : playerToGive.UserIDString)}] custom item [{uniqueShortname}]!");
            }
            else {
                if (arg.Player() != null) {
                    arg.ReplyWith($"Item with name \"{uniqueShortname}\" was not found!");
                    return;
                }
                PrintError($"Item with name \"{uniqueShortname}\" was not found!");
            }
        }
#endregion
#region Classes
        public class CustomItem : WeaponData {
            public class UISettings {
                [JsonProperty(PropertyName = "Name Color (or use <color></color> in name)")]
                public string NameColor {
                    get;
                    set;
                }
                = "1 1 1 1";
                [JsonProperty(PropertyName = "Frame Color")]
                public string FrameColor {
                    get;
                    set;
                }
                = "0.94 0.75 0.15 1";
            }
            [JsonProperty(PropertyName = "Name")]
            public string Name {
                get;
                set;
            }
            = "";
            [JsonProperty(PropertyName = "Description")]
            public string Description {
                get;
                set;
            }
            = "";
            [JsonProperty(PropertyName = "SkinId")]
            public ulong SkinId {
                get;
                set;
            }
            = 0;
            //[JsonProperty(PropertyName = "Permission for use")]
            //public string Permission { get; set; } = string.Empty;
            [JsonProperty(PropertyName = "UI Settings")]
            public UISettings UiSettings {
                get;
                set;
            }
            = new UISettings();
        }
        public class WeaponData {
            public class EffectsEntitySettings {
                public class __ValuesSettings {
                    [JsonProperty(PropertyName = "Max Radiation Poison")]
                    public float MaxRadPoison {
                        get;
                        set;
                    }
                    = 500;
                    [JsonProperty(PropertyName = "Max Bleading")]
                    public float MaxBleading {
                        get;
                        set;
                    }
                    = 100;
                    [JsonProperty(PropertyName = "Min Temperature")]
                    public float MinTemperature {
                        get;
                        set;
                    }
                    = -100;
                    [JsonProperty(PropertyName = "Max Temperature")]
                    public float MaxTemperature {
                        get;
                        set;
                    }
                    = 100;
                    [JsonProperty(PropertyName = "Max Wetness")]
                    public float MaxWetness {
                        get;
                        set;
                    }
                    = 100;
                }
                [JsonProperty(PropertyName = "Maximum and minimum values in the accumulation")]
                public __ValuesSettings ValuesSettings {
                    get;
                    set;
                }
                = new __ValuesSettings();
                [JsonProperty(PropertyName = "Radiation Poison")]
                public float RadPoison {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Bleading")]
                public float Bleeding {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Temperature")]
                public float Temperature {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Hunger")]
                public float Hunger {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Thirst")]
                public float Thirst {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Wetness")]
                public float Wetness {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Number of electric balls (recommended to 10)")]
                public int ElecticBalls {
                    get;
                    set;
                }
            }
            public class EffectsGroundSettings {
                [JsonProperty(PropertyName = "Electric Ball")]
                public bool ElecticBall {
                    get;
                    set;
                }
            }
            [JsonProperty(PropertyName = "Shortname")]
            public string Shortname {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Unbreakable", NullValueHandling = NullValueHandling.Ignore)]
            public bool Unbreakable {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Durability", DefaultValueHandling = DefaultValueHandling.Ignore)]
            public float Durability {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Fast Reload")]
            public bool FastReload {
                get;
                set;
            }
            = false;
            [JsonProperty(PropertyName = "Magazine Capacity", DefaultValueHandling = DefaultValueHandling.Ignore)]
            public int MagazineCapacity {
                get;
                set;
            }
            [JsonProperty(PropertyName = "Effects when hit")]
            public EffectsEntitySettings EffectsEntity {
                get;
                set;
            }
            = new EffectsEntitySettings();
            [JsonProperty(PropertyName = "Effects when hit the ground")]
            public EffectsGroundSettings EffectsGround {
                get;
                set;
            }
            = new EffectsGroundSettings();
            [JsonProperty(PropertyName = "Base damage by type & ammo", NullValueHandling = NullValueHandling.Ignore)]
            public Dictionary<string, Dictionary<string, float>> DamageTypes {
                get;
                set;
            }
            [JsonIgnore]
            public Dictionary<string, Rust.DamageTypeList> DamageTypeList {
                get;
                set;
            }
            = new Dictionary<string, Rust.DamageTypeList>();
        }
#endregion
#region Fields
        private static List<Rust.DamageType> DamageTypesExсeptions = new List<Rust.DamageType>() {
            Rust.DamageType.Generic, Rust.DamageType.LAST, Rust.DamageType.Decay, Rust.DamageType.RadiationExposure, Rust.DamageType.ColdExposure, Rust.DamageType.Fun_Water, Rust.DamageType.Suicide, Rust.DamageType.Fall,
        }
        ;
        private static List<Rust.DamageType> DamageTypes = Enum.GetValues(typeof(Rust.DamageType)).Cast<Rust.DamageType>().Where(type => !DamageTypesExсeptions.Contains(type)).ToList();
        private static Dictionary<Rust.DamageType, string> DamageTypeNames = DamageTypes.ToDictionary(type => type, type => Enum.GetName(typeof(Rust.DamageType), type));
        private static Dictionary<string, Dictionary<string, Rust.DamageTypeList>> DefaultDamageWeapons = new Dictionary<string, Dictionary<string, Rust.DamageTypeList>>();
#endregion
#region Methods
        private void SetName(Item item, WeaponData weaponData, string itemName = null) {
            if (item == null || weaponData == null) return;
            item.name = itemName;
            item.streamerName = null;
            if (!config.ItemSelectInfo) return;
            BasePlayer owner = item.GetOwnerPlayer();
            Dictionary<string, string> translation = null;
            if (RustTranslationAPI != null && (itemName == null || itemName == string.Empty)) translation = RustTranslationAPI.Call<Dictionary<string, string>>("GetTranslations", lang.GetLanguage(owner?.UserIDString));
            if (itemName == null || itemName == string.Empty) {
                if (translation == null || !translation.TryGetValue($"{item.info.shortname}", out itemName)) itemName = item.info.displayName.translated;
            }
            Rust.DamageTypeList damageTypeListToRender = null;
            BaseEntity heldEntity = item.GetHeldEntity();
            if (heldEntity != null) {
                BaseProjectile baseProjectile = heldEntity as BaseProjectile;
                if (baseProjectile != null && baseProjectile.primaryMagazine != null) {
                    ItemDefinition ammoDef = baseProjectile.primaryMagazine.ammoType;
                    if (ammoDef != null) {
                        weaponData.DamageTypeList.TryGetValue(ammoDef.shortname, out damageTypeListToRender);
                    }
                }
            }
            if (damageTypeListToRender == null && weaponData.DamageTypeList.Count > 0) damageTypeListToRender = weaponData.DamageTypeList.First().Value;
            if (damageTypeListToRender == null) return;
            Dictionary<string, float> FieldsForRender = DamageTypes.ToDictionary(x => GetMessage(DamageTypeNames[x], owner?.UserIDString), x => damageTypeListToRender.Get(x));
            FieldsForRender = FieldsForRender.Where(i => i.Value != 0f).ToDictionary(i => i.Key, i => i.Value);
            StringBuilder stringBuilder = new StringBuilder();
            stringBuilder.Append(string.Concat(Enumerable.Repeat("\n", FieldsForRender.Count * 2 + 8)));
            stringBuilder.Append($"\n{itemName}");
            stringBuilder.Append("\n\t\t\t\t\t\t\t\t\t\t\t\t" + GetMessage(LangKeys.ItemInfoPanelHeader, owner?.UserIDString));
            foreach (var pair in FieldsForRender) {
                string keyWithoutRichtext = Regex.Replace(pair.Key, "<.*?>", String.Empty);
                stringBuilder.Append("\n\t\t\t\t\t\t\t\t\t\t\t\t   ");
                stringBuilder.Append(" " + keyWithoutRichtext);
                stringBuilder.Append("\n\t\t\t\t\t\t\t\t\t\t\t\t\t   ");
                stringBuilder.Append(pair.Value);
            }
            stringBuilder.Append("\n\n\t\t\t\t\t\t\t\t\t\t\t\t" + GetMessage(LangKeys.CharacteristicsPanelHeader, owner?.UserIDString));
            stringBuilder.Append("\n\t\t\t\t\t\t\t\t\t\t\t\t    " + GetMessage(LangKeys.MagazineCapacity, owner?.UserIDString));
            stringBuilder.Append("\n\t\t\t\t\t\t\t\t\t\t\t\t\t    " + weaponData.MagazineCapacity);
            stringBuilder.Append("\n\t\t\t\t\t\t\t\t\t\t\t\t    " + GetMessage(LangKeys.MaxDurability, owner?.UserIDString));
            stringBuilder.Append("\n\t\t\t\t\t\t\t\t\t\t\t\t\t    " + weaponData.Durability);
            stringBuilder.Append("\n\t\t\t\t\t\t\t\t\t\t\t\t    " + GetMessage(LangKeys.Unbreakable, owner?.UserIDString));
            stringBuilder.Append("\n\t\t\t\t\t\t\t\t\t\t\t\t\t    " + (weaponData.Unbreakable ? GetMessage(LangKeys.Yes, owner?.UserIDString) : GetMessage(LangKeys.No, owner?.UserIDString)));
            item.streamerName = stringBuilder.ToString();
            item.MarkDirty();
        }
        private bool TryGetCustomItem(Item item, out CustomItem customItem) => TryGetCustomItem(item.info, out customItem);
        private bool TryGetCustomItem(ItemDefinition info, out CustomItem customItem) {
            if (!info.HasFlag(CUSTOMWEAPON_FLAG) || !TryGetCustomItemByKey(info.shortname, out customItem)) {
                customItem = null;
                return false;
            }
            return true;
        }
        private bool HasCustomItemWithKey(string key) {
            return config.DataItems.Custom.ContainsKey(key);
        }
        private bool TryGetCustomItemByKey(string key, out CustomItem customItem) {
            if (key == null || config?.DataItems?.Custom == null) {
                customItem = null;
                return false;
            }
            return config.DataItems.Custom.TryGetValue(key, out customItem);
        }
        private bool TryGetWeaponData(BasePlayer player, Item item, out WeaponData weaponData) => TryGetWeaponData(player, item.info, out weaponData);
        private bool TryGetWeaponData(BasePlayer player, ItemDefinition info, out WeaponData weaponData) {
            CustomItem customItem;
            if (TryGetCustomItem(info, out customItem)) {
                weaponData = customItem;
                return true;
            }
            else return TryGetDefaultWeaponData(player, info, out weaponData);
        }
        private bool TryGetDefaultWeaponData(BasePlayer player, Item item, out WeaponData weaponData) => TryGetDefaultWeaponData(player, item.info, out weaponData);
        private bool TryGetDefaultWeaponData(BasePlayer player, ItemDefinition info, out WeaponData weaponData) {
            try {
                if (!config.DataItems.Default.TryGetValue(info.shortname, out weaponData)) return false;
                if (player != null) {
                    foreach (var perm in config.DataItems.Permissions) {
                        WeaponData tempWd = null;
                        if (perm.Value.TryGetValue(info.shortname, out tempWd) && permission.UserHasPermission(player.UserIDString, $"customizableweapons.{perm.Key}")) {
                            weaponData = tempWd;
                            break;
                        }
                    }
                }
                return weaponData != null;
            }
            catch {
                weaponData = default(WeaponData);
                return false;
            }
        }
        private bool IsWeapon(Item item) {
            var heldEntity = item.GetHeldEntity();
            return heldEntity is BaseProjectile || heldEntity is BaseMelee || heldEntity is ThrownWeapon || heldEntity is FlameThrower;
        }
        private void UpdateHitDamage(HitInfo info, BaseEntity entity, float scale = 1f) {
            // Yeni eklenen kontrol
            if (config.GlobalSettings.DisableWeaponDamage) {
                return;
                // Eğer yapılandırmada silah hasarı devre dışı bırakıldıysa, bu işlemi atla
            }
            if (info.Weapon is BaseProjectile) {
                var shootableWeapon = info.Weapon as BaseProjectile;
                var item = shootableWeapon.GetCachedItem();
                if (item == null) return;
                var ammotypeShortname = shootableWeapon.primaryMagazine.ammoType.shortname;
                if (ammotypeShortname == null) return;
                WeaponData weaponData = null;
                if (TryGetWeaponData(entity.ToPlayer(), item, out weaponData)) {
                    Rust.DamageTypeList damageTypeList = null;
                    if (!weaponData.DamageTypeList.TryGetValue(ammotypeShortname, out damageTypeList)) {
                        PrintWarning($"There is no damage list in the item configuration (Shortname: {weaponData.Shortname})");
                        return;
                    }
                    for (int i = 0; i < damageTypeList.types.Length; i++) {
                        info.damageTypes.types[i] = damageTypeList.types[i] * scale;
                    }
                }
            }
            // Melee ve diğer silah tipleri için devam eder...if (info.Weapon is BaseProjectile)
            {
                var shootableWeapon = info.Weapon as BaseProjectile;
                var item = shootableWeapon.GetCachedItem();
                if (item == null) return;
                var ammotypeShortname = shootableWeapon.primaryMagazine.ammoType.shortname;
                if (ammotypeShortname == null) return;
                WeaponData weaponData = null;
                if (TryGetWeaponData(entity.ToPlayer(), item, out weaponData)) {
                    Rust.DamageTypeList damageTypeList = null;
                    if (!weaponData.DamageTypeList.TryGetValue(ammotypeShortname, out damageTypeList)) {
                        PrintWarning($"There is no damage list in the item configuration (Shortname: {weaponData.Shortname})");
                        return;
                    }
                    for (int i = 0; i < damageTypeList.types.Length; i++) {
                        info.damageTypes.types[i] = damageTypeList.types[i] * scale;
                    }
                }
            }
            else if (info.Weapon is BaseMelee) {
                var meleeWeapon = info.Weapon as BaseMelee;
                var item = meleeWeapon.GetCachedItem();
                if (item == null) return;
                string attackType = (info.IsProjectile() ? "throw" : "melee");
                WeaponData weaponData = null;
                if (TryGetWeaponData(entity.ToPlayer(), item, out weaponData)) {
                    Rust.DamageTypeList damageTypeList = null;
                    if (!weaponData.DamageTypeList.TryGetValue(attackType, out damageTypeList)) {
                        PrintWarning($"There is no damage list in the item configuration (Shortname: {weaponData.Shortname})");
                        return;
                    }
                    for (int i = 0; i < damageTypeList.types.Length; i++) info.damageTypes.types[i] = damageTypeList.types[i] * scale;
                }
            }
            else if (info.Weapon is FlameThrower) {
                var flameThrower = info.Weapon as FlameThrower;
                var item = flameThrower.GetCachedItem();
                if (item == null) return;
                WeaponData weaponData = null;
                if (TryGetWeaponData(entity.ToPlayer(), item, out weaponData)) {
                    Rust.DamageTypeList damageTypeList = null;
                    if (!weaponData.DamageTypeList.TryGetValue("ammo.lowgrade", out damageTypeList)) {
                        PrintWarning($"There is no damage list in the item configuration (Shortname: {weaponData.Shortname})");
                        return;
                    }
                    for (int i = 0; i < damageTypeList.types.Length; i++) info.damageTypes.types[i] = damageTypeList.types[i] * scale;
                }
            }
        }
        private void UpdateHitDamage(List<Rust.DamageTypeEntry> damageTypes, Item item, BaseEntity entity, float scale = 1f) {
            if (item == null || damageTypes == null) return;
            var type = string.Empty;
            var heldEntity = item.GetHeldEntity();
            if (heldEntity is BaseProjectile) type = (heldEntity as BaseProjectile).primaryMagazine.ammoType.shortname;
            if (heldEntity is ThrownWeapon) type = "throw";
            if (heldEntity is FlameThrower) type = "ammo.lowgrade";
            WeaponData weaponData;
            if (TryGetWeaponData(entity.ToPlayer(), item, out weaponData)) {
                if (weaponData.DamageTypeList == null) return;
                Rust.DamageTypeList damageTypeList = null;
                if (!weaponData.DamageTypeList.TryGetValue(type, out damageTypeList)) {
                    PrintWarning($"There is no damage list in the item configuration (Shortname: {weaponData.Shortname})");
                    return;
                }
                if (damageTypeList.types.Length > 0) {
                    damageTypes.Clear();
                    for (int i = 0; i < damageTypeList.types.Length; i++) {
                        damageTypes.Add(new Rust.DamageTypeEntry() {
                            type = (Rust.DamageType)i, amount = damageTypeList.types[i] * scale
                        }
                        );
                    }
                }
            }
        }
        void SetupMagizineCapacity(BaseProjectile weapon) {
            if (weapon == null) return;
            // Yeni eklenen kontrol
            if (config.GlobalSettings.DisableMagazineCapacity) {
                re
// ... [Code preview truncated due to length. Full source in attached file] ...

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