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

FREE MountableTurrets : 1.2.1 1.2.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
//Requires: ImageLibrary
using Network;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Game.Rust.Cui;
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using HarmonyLib;
namespace Oxide.Plugins {
    [Info("MountableTurrets", "https://discord.gg/TrJ7jnS233", "1.2.1")]
    class MountableTurrets : RustPlugin {
#region Dependencies
        [PluginReference]
        Plugin ImageLibrary, ServerRewards;
        static void AddImage(string url, string name) => Instance.ImageLibrary.Call("AddImage", url, name);
        static string GetImageID(string name) => (string)Instance.ImageLibrary.Call("GetImage", name) ?? "";
        static bool? AddPoints(ulong playerID, int amount) => Instance.ServerRewards.Call("AddPoints", playerID, amount) as bool?;
        static bool? TakePoints(ulong playerID, int amount) => Instance.ServerRewards.Call("TakePoints", playerID, amount) as bool?;
        static int? CheckPoints(ulong ID) => Instance.ServerRewards.Call("CheckPoints", ID) as int?;
#endregion
#region Constants
        const string GUN_PREFAB = "assets/prefabs/weapons/m249/m249.entity.prefab";
        const string COMP_STATION_PREFAB = "assets/prefabs/deployable/computerstation/computerstation.deployed.prefab";
        const string CCTV_PREFAB = "assets/prefabs/deployable/cctvcamera/cctv.static.prefab";
        const string ROCKET_LAUNCHER_PREFAB = "assets/prefabs/weapons/rocketlauncher/rocket_launcher.entity.prefab";
        const string MOUNTABLE_PREFAB = "assets/prefabs/vehicle/seats/standingdriver.prefab";
        const string SPINNER_PREFAB = "assets/prefabs/deployable/spinner_wheel/spinner.wheel.deployed.prefab";
        const string SIGN_PREFAB = "assets/prefabs/deployable/signs/sign.small.wood.prefab";
        const string LOOTABLE_PREFAB = "assets/prefabs/misc/item drop/item_drop.prefab";
        const string FLARE_PREFAB = "assets/prefabs/tools/flareold/flare.deployed.prefab";
        const string HV_ROCKET_PREFAB = "assets/prefabs/ammo/rocket/rocket_hv.prefab";
        const string EFFECT_CODELOCK_LOCK = "assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab";
        const string EFFECT_CODELOCK_UNLOCK = "assets/prefabs/locks/keypad/effects/lock.code.lock.prefab";
        const string EFFECT_PAGER_BEEP = "assets/prefabs/tools/pager/effects/beep.prefab";
        const string FLARE_ICON = "assets/prefabs/tools/flareold/flare.png";
        const string CROSSHAIR_CUI = "MountableTurrets_crosshair";
        const string AA_CROSSHAIR_CUI = "MountableTurrets_aa_crosshair";
        const string ACQUIRING_TARGET_CUI = "MountableTurrets_acquiringTarget";
        const string ACQUIRING_TARGET_PARENT_CUI = "MountableTurrets_acquringTargetParent";
        const string TARGET_DISTANCE_CUI = "MountableTurrets_targetdistance";
        const string TARGET_INFO_CUI = "MountableTurrets_targetinfo";
        const string MODE_CUI = "MountableTurrets_mode";
        const string TARGET_LOST_CUI = "MountableTurrets_target_lost";
        const string RELOADING_CUI = "MountableTurrets_reloading";
        const string CONTROLS_HELP_CUI = "MountableTurrets_controlshelp";
        const string LOCKED_UI_CUI = "MountableTurrets_lockedui";
        const string AA_TURRET_CUI = "MountableTurrets_aaturretui";
        const string IRTRAP_CUI = "MountableTurrets_IRtrap";
        const string NO_AMMO_CUI = "MountableTurrets_noammo";
        const string CHANGEMODE_BTN_CUI = "MountableTurrets_changeModeBtn";
        const string FIRE_BTN_CUI = "MountableTurrets_fireBtn";
        const string FIRE_CCMD = "mountableturrets.fire";
        const string CHANGEMODE_CCMD = "mountableturrets.changemode";
        const string AA_TURRET_GIVE_PERMISSION = "mountableturrets.aaturret.give";
        const string AA_TURRET_FREE_PERMISSION = "mountableturrets.aaturret.free";
        const string MACHINEGUN_TURRET_FREE_PERMISSION = "mountableturrets.machinegun.free";
        const string MACHINEGUN_TURRET_GIVE_PERMISSION = "mountableturrets.machinegun.give";
        const string ADMIN_PERMISSION = "mountableturrets.admin";
        const string SAVES_DATAFILE_NAME = "MountableTurrets_PlayerGeneratedData";
        const string MONUMENT_DATAFILE_NAME = "MountableTurrets_MonumentData";
        const float MACHINEGUNTURRET_CLAMP_ANGLE = 40f;
        const int SPINNER_ITEMID = -1100422738;
#endregion
#region Fields
        static MountableTurrets Instance;
        static List<BaseEntity> TurretEntities;
        static Dictionary<BaseMountable, MachineGunTurret> TurretMountables;
        static Dictionary<string, AATurret> AATurrets;
        static Dictionary<BaseEntity, int> IRTrapCount;
        static Dictionary<BasePlayer, AATurret> PlayersCurrentlyControllingRCTurrets;
        static List<AARocket> AARockets;
        static List<MachineGunTurret> MachineGunTurrets;
        static List<BaseEntity> AASpinners;
        static List<BaseEntity> MachineGunSpinners;
        static List<ItemContainer> AATurretContainers;
        static List<ItemContainer> MachineGunTurretContainers;
        static Dictionary<BaseCombatEntity, float> LastIRTrapUse;
        static Dictionary<MonumentInfo, List<ISpawnable>> MonumentSpawnables;
        static ItemDefinition MachineGunTurretAmmoType;
        static List<BaseCombatEntity> IndestructibleEntities;
        static bool isPluginInitialized;
        static DataFileSystem dataFiles;
#endregion
#region Configuration
        class Configuration : SerializableConfiguration {
            [JsonProperty("PVE Mode (true/false)")]
            public bool PVE = false;
            [JsonProperty("[AA Turret] Price (set value to 0 to make it free, use ServerRewards as a key to use RP points)")]
            public KeyValuePair<string, int> AATurret_Price = new KeyValuePair<string, int>("scrap", 500);
            [JsonProperty("[AA Turret] Item Skin ID (Workshop ID)")]
            public ulong AATurret_Item_SkinID = 2849832768;
            [JsonProperty("[AA Turret] Item Name")]
            public string AATurret_Item_Name = "Anti-Aerial Turret";
            [JsonProperty("[AA Turret] Cooldown between shots (seconds)")]
            public float AATurret_Rocket_Cooldown = 10f;
            [JsonProperty("[AA Turret] Rocket fuse length (seconds)")]
            public float AATurret_Rocket_FuseLength = 10f;
            [JsonProperty("[AA Turret] Rocket fuse length (meters)")]
            public float AATurret_MaxLockOnDistance = 450f;
            [JsonProperty("[AA Turret] Entities that turret is able to lock on to (short prefab name)")]
            public string[] AATurret_AbleToLockOn = new string[] {
                "minicopter.entity", "scraptransporthelicopter", "hotairballoon"
            }
            ;
            [JsonProperty("[AA Turret] Infinite ammo (true/false)")]
            public bool AATurret_InfiniteAmmo = true;
            [JsonProperty("[AA Turret] Ammo item shortname")]
            public string AATurret_AmmoShortname = "ammo.rocket.hv";
            [JsonProperty("[AA Turret] Amount per shot")]
            public int AATurret_AmountPerShot = 1;
            [JsonProperty("[AA Turret] Target acquiring time (seconds)")]
            public float AATurret_TargetAcquiringTime = 0.6f;
            [JsonProperty("[AA Turret] Rocket initial velocity (meters per second)")]
            public float AATurret_Rocket_InitialVelocity = 30f;
            [JsonProperty("[AA Turret] Interval between shots in Burst mode (seconds)")]
            public float AATurret_Rocket_FireInterval = 0.4f;
            [JsonProperty("[AA Turret] Rocket explosion radius (meters)")]
            public float AATurret_Rocket_ExplosionRadius = 5f;
            [JsonProperty("[AA Turret] Movement Speed Fast")]
            public float AATurret_Speed_Fast = 3.7f;
            [JsonProperty("[AA Turret] Movement Speed Normal")]
            public float AATurret_Speed_Norm = 2f;
            [JsonProperty("[AA Turret] Movement Speed Slow")]
            public float AATurret_Speed_Slow = 1f;
            [JsonProperty("[AA Turret] Turret HP")]
            public float AATurret_HP = 50;
            [JsonProperty("[AA Turret] Damage multipliers (e.g.1.0 - vanilla, 2.0 - 2x more damage, 0.5 - half of vanilla damage)")]
            public Dictionary<string, float> AATurret_DamageMultipliers = new Dictionary<string, float>() {
                {
                    "vehicle", 1.0f
                }
                , {
                    "buildingblock", 1.0f
                }
                , {
                    "player", 1.0f
                }
                , {
                    "other", 1.0f
                }
            }
            ;
            [JsonProperty("[Machine Gun Turret] Price (set value to 0 to make it free, use ServerRewards as a key to use RP points)")]
            public KeyValuePair<string, int> MachinegunTurret_Price = new KeyValuePair<string, int>("scrap", 250);
            [JsonProperty("[Machine Gun Turret] Infinite ammo (true/false)")]
            public bool MachinegunTurret_InfiniteAmmo = true;
            [JsonProperty("[Machine Gun Turret] Ammo item shortname")]
            public string MachinegunTurret_AmmoShortname = "ammo.rifle";
            [JsonProperty("[Machine Gun Turret] Amount per shot")]
            public int MachinegunTurret_AmountPerShot = 1;
            [JsonProperty("[Machine Gun Turret] Item Skin ID (Workshop ID)")]
            public ulong MachinegunTurret_Item_SkinID = 2849176974;
            [JsonProperty("[Machine Gun Turret] Item Name")]
            public string MachinegunTurret_Item_Name = "Machine Gun Turret";
            [JsonProperty("[Machine Gun Turret] Ammo type (short prefab name, must be one of 5.56 Rifle ammo)")]
            public string MachinegunTurret_AmmoType = "ammo.rifle";
            [JsonProperty("[Machine Gun Turret] Turret HP")]
            public float MachinegunTurret_HP = 50;
            // [JsonProperty("[IR Trap] Stack size")] public int IRTrap_StackSize = 12;
            // [JsonProperty("[IR Trap] Amount per use")]
            // public int IRTrap_SpendPerUse = 2;
            // [JsonProperty("[IR Trap] Cooldown (seconds)")]
            // public float IRTrap_Cooldown = 3f;
            // [JsonProperty("[IR Trap] Initial velocity (meters per seconds)")]
            // public float IRTrap_InitialVelocity = 20f;
            // [JsonProperty("[IR Trap] Fuse length (seconds)")]
            // public float IRTrap_FuseLength = 10f;
            // [JsonProperty("[IR Trap] Affects SAM Sites (true/false)")]
            // public bool IRTrap_AffectSAMSites = true;
            // [JsonProperty("[IR Trap] SAM Site blind time (seconds)")]
            // public float IRTrap_SAMSiteBlindTime = 5f;
            // [JsonProperty("[IR Trap] Show IR-Trap hint UI (true/false)")]
            // public bool ShowIRTrapInfoText = true;
            // [JsonProperty("[IR Trap] Deploy positions")]
            // public Dictionary<string, List<PositionData>> IRTrap_DeployPositions = new Dictionary<string, List<PositionData>>
            // {
            //     {
            //         "minicopter.entity",
            //         new List<PositionData>
            //         {
            //             new PositionData(new Vector3(-0.582f, 0.6621f, -0.4615f), Vector3.left),
            //             new PositionData(new Vector3(0.556f, 0.6651f, -0.5f), Vector3.right)
            //         }
            //     },
            //     {
            //         "scraptransporthelicopter",
            //         new List<PositionData>
            //         {
            //             new PositionData(new Vector3(2.151f, 0.373f, -1.129f), Vector3.right),
            //             new PositionData(new Vector3(-2.43899f, 0.375f, -0.977f), Vector3.left)
            //         }
            //     },
            // };
            [JsonProperty("[Misc] Spawn positions on other entities (full prefab name)")]
            public Dictionary<string, List<SerializedConfigSaveEntry>> EntityTurrets = new Dictionary<string, List<SerializedConfigSaveEntry>>() {
                {
                    "assets/content/vehicles/modularcar/module_entities/2module_flatbed.prefab", new List<SerializedConfigSaveEntry>() {
                        new SerializedConfigSaveEntry() {
                            Type = "MachinegunTurret", Position = new Vector3(-0.01828f, 0.16f, -1.6145f), Rotation = new Vector3(0, 180f, 0)
                        }
                    }
                }
                ,
                /*                { "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", new List<SerializedConfigSaveEntry>() {
                    new SerializedConfigSaveEntry()
                    {
                        Type = "MachinegunTurret",
                        Position = new Vector3(0.84f, 0.8f, -0.629f),
                        Rotation = new Vector3(0, 90f, 0)
                    },
                    new SerializedConfigSaveEntry()
                    {
                        Type = "MachinegunTurret",
                        Position = new Vector3(-0.87f, 0.8f, 0.348f),
                        Rotation = new Vector3(0, 270f, 0)
                    },
                } }, */
                {
                    "assets/content/vehicles/trains/wagons/trainwagonb.entity.prefab", new List<SerializedConfigSaveEntry>() {
                        new SerializedConfigSaveEntry() {
                            Type = "MachinegunTurret", Position = new Vector3(0.974f, 1.545f, 3.276f), Rotation = new Vector3(0, 90f, 0)
                        }
                        , new SerializedConfigSaveEntry() {
                            Type = "MachinegunTurret", Position = new Vector3(-1.035f, 1.545f, -3.35f), Rotation = new Vector3(0, 270f, 0)
                        }
                        ,
                    }
                }
                , {
                    "assets/content/vehicles/trains/wagons/trainwagona.entity.prefab", new List<SerializedConfigSaveEntry>() {
                        new SerializedConfigSaveEntry() {
                            Type = "MachinegunTurret", Position = new Vector3(-0.98385f, 1.528f, 2.98f), Rotation = new Vector3(0, 270, 0)
                        }
                    }
                }
                , {
                    "assets/content/vehicles/boats/cargoship/cargoshiptest.prefab", new List<SerializedConfigSaveEntry>() {
                        new SerializedConfigSaveEntry() {
                            Type = "MachinegunTurret", Position = new Vector3(-11.52f, 6.463f, -4.375f), Rotation = new Vector3(0, 270f, 0)
                        }
                        , new SerializedConfigSaveEntry() {
                            Type = "MachinegunTurret", Position = new Vector3(-11.5193f, 6.475f, 25.335f), Rotation = new Vector3(0, 270f, 0)
                        }
                        , new SerializedConfigSaveEntry() {
                            Type = "MachinegunTurret", Position = new Vector3(11.5493f, 6.488f, -4.362f), Rotation = new Vector3(0, 90f, 360f)
                        }
                        , new SerializedConfigSaveEntry() {
                            Type = "MachinegunTurret", Position = new Vector3(11.552f, 6.5f, 25.329f), Rotation = new Vector3(0, 90, 0f)
                        }
                        , new SerializedConfigSaveEntry() {
                            Type = "AATurret", Position = new Vector3(0.791f, 9.472f, 75.623f), Rotation = new Vector3(0, 180f, 0f)
                        }
                        , new SerializedConfigSaveEntry() {
                            Type = "AATurret", Position = new Vector3(-5.977f, 27.495f, -45.049f), Rotation = new Vector3(0, 0, 0)
                        }
                        , new SerializedConfigSaveEntry() {
                            Type = "AATurret", Position = new Vector3(6, 27.495f, -45.003f), Rotation = new Vector3(0, 0, 0)
                        }
                        , new SerializedConfigSaveEntry() {
                            Type = "ComputerStation", Position = new Vector3(-4.791f, 24.498f, -44.161f), Rotation = new Vector3(0, 0, 0)
                        }
                        , new SerializedConfigSaveEntry() {
                            Type = "ComputerStation", Position = new Vector3(-0.007f, 3.5f, 51.7f), Rotation = new Vector3(0, 0, 0)
                        }
                        ,
                    }
                }
            }
            ;
            [JsonProperty("[Misc] UI Images (leave names intact)")]
            public Dictionary<string, string> CUI_Images = new Dictionary<string, string>() {
                {
                    @"https://i.imgur.com/lXTORE5.png", "MountableTurrets_crosshair"
                }
                , {
                    @"https://i.imgur.com/7VyNdEh.png", "MountableTurrets_aa_crosshair"
                }
                , {
                    @"https://i.imgur.com/IH0KzHK.png", "MountableTurrets_aa_crosshair_locked"
                }
                , {
                    @"https://i.imgur.com/ZvjYx8J.png", "MountableTurrets_line"
                }
                ,
            }
            ;
        }
        class SerializedConfigSaveEntry {
            public string Type;
            public Vector3 Position;
            public Vector3 Rotation;
        }
#endregion
#region Configuration Boilerplate
        static Configuration config;
        private class SerializableConfiguration {
            public string ToJson() => JsonConvert.SerializeObject(this);
            public Dictionary<string, object> ToDictionary() => JsonHelper.Deserialize(ToJson()) as Dictionary<string, object>;
        }
        private static class JsonHelper {
            public static object Deserialize(string json) => ToObject(JToken.Parse(json));
            private static object ToObject(JToken token) {
                switch (token.Type) {
                    case JTokenType.Object : return token.Children<JProperty>().ToDictionary(prop => prop.Name, prop => ToObject(prop.Value));
                    case JTokenType.Array : return token.Select(ToObject).ToList();
                    default : return ((JValue)token).Value;
                }
            }
        }
        private bool ValidateConfig(Dictionary<string, object> currentWithDefaults, Dictionary<string, object> currentRaw) {
            var changed = false;
            var oldKeys = new List<string>();
            foreach (var key in currentRaw.Keys) {
                if (currentWithDefaults.Keys.Contains(key)) {
                    continue;
                }
                changed = true;
                oldKeys.Add(key);
            }
            foreach (var key in oldKeys) {
                currentRaw.Remove(key);
            }
            foreach (var key in currentWithDefaults.Keys) {
                object currentRawValue;
                if (currentRaw.TryGetValue(key, out currentRawValue)) {
                    var defaultDictValue = currentWithDefaults[key] as Dictionary<string, object>;
                    var currentDictValue = currentRawValue as Dictionary<string, object>;
                    if (defaultDictValue != null) {
                        if (currentDictValue == null) {
                            currentRaw[key] = currentWithDefaults[key];
                            changed = true;
                            continue;
                        }
                        if (ValidateConfig(defaultDictValue, currentDictValue)) {
                            changed = true;
                        }
                    }
                    continue;
                }
                currentRaw[key] = currentWithDefaults[key];
                changed = true;
            }
            return changed;
        }
        protected override void LoadDefaultConfig() => config = new Configuration();
        protected override void LoadConfig() {
            base.LoadConfig();
            try {
                config = Config.ReadObject<Configuration>();
                if (config == null) {
                    throw new JsonException();
                }
                var currentWithDefaults = config.ToDictionary();
                var currentRaw = Config.ToDictionary(x => x.Key, x => x.Value);
                if (ValidateConfig(currentWithDefaults, currentRaw)) {
                    PrintWarning("Configuration appears to be outdated; updating and saving");
                    SaveConfig();
                }
            }
            catch {
                PrintWarning($"Configuration file {Name}.json is invalid; using defaults");
                LoadDefaultConfig();
            }
        }
        protected override void SaveConfig() {
            Puts($"Configuration changes saved to {Name}.json");
            Config.WriteObject(config, true);
        }
#endregion
#region Localization
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["AATurret_ControlsHelp"]
                = "W A S D - move camera\nCTRL - move slowly\nSHIFT -   move fast\nSPACE -    dismount", ["IRTrap_InfoText"] = "You can add IR-traps (flares) to your vehicle to avoid getting shot by anti-aerial missiles.\n\nPress [USE] to deploy IR-traps", ["noPerms"] = "You don't have permission to use this command", ["noMonument"] = "You must be standing in a monument to use this command", ["playerDataWiped"] = "Player data is wiped!", ["mtUsage"] = "Usage: /mt add/remove/reset", ["mtAddUsage"] = "Usage: /mt add aa/mg/comp", ["lookAtTurret"] = "You are not looking at a turret", ["lookAtSurface"] = "Look at the surface you want to spawn on", ["allRemoved"] = "Wiped all data for {0}", ["addedToMonument"] = "Added to {0}", ["removedFromMonument"] = "Removed from {0}", ["notEnoughPoints"] = "You don't have enough points to buy this turret", ["notEnoughResources"] = "You don't have enough {0} to buy this turret", ["mgTurretGiven"] = "Machinegun turret has been given to you", ["aaTurretGiven"] = "Anti-Aerial turret has been given to you", ["reloading"] = "RELOADING...", ["targetLost"] = "TARGET LOST", ["targetAcquired"] = "TARGET ACQUIRED", ["acquiringTarget"] = "ACQUIRING TARGET...", ["lockedOnTarget"] = "LOCKED ON TARGET", ["waitingForTarget"] = "WAITING FOR TARGET", ["manualSingle"] = "MANUAL (SINGLE)", ["manualBurst"] = "MANUAL (BURST)", ["aaTurretIDIs"] = "AATurret ID is: {0}", ["noAmmo"] = "NO AMMO", ["irTrapStorage"] = "IR-TRAP STORAGE", ["noIRTraps"] = "You've ran out of IR-Traps", ["fire"] = "FIRE", ["changeMode"] = "CHANGE MODE",
            }
            , this, "en");
            lang.RegisterMessages(new Dictionary<string, string> {
                ["AATurret_ControlsHelp"]
                = "W A S D - двигать камерой\nCTRL - двигаться медленно\nSHIFT -   двигаться быстро\nПРОБЕЛ -    выйти", ["IRTrap_InfoText"] = "Вы можете добавить ИК-ловушки, чтобы исбежать попадания ракет.\n\nНажмите [Е] чтобы выпустить ИК-ловушки", ["noPerms"] = "У вас нет доступа к этой команде", ["noMonument"] = "Вы должны стоять на РТ для использования этой команды", ["playerDataWiped"] = "Вся информация сброшена!", ["mtUsage"] = "Использование: /mt add/remove/reset", ["mtAddUsage"] = "Использование: /mt add aa/mg/comp", ["lookAtTurret"] = "Вы не смотрите на турель", ["lookAtSurface"] = "Смотрите на поверхность на которой хотите заспаунить турель", ["allRemoved"] = "Вся информация для {0} очищена!", ["addedToMonument"] = "Добавлено в {0}", ["removedFromMonument"] = "Удалено с {0}", ["notEnoughPoints"] = "У вас не хватает очков для покупки этой турели", ["notEnoughResources"] = "У вас не хватает {0} для покупки этой турели", ["mgTurretGiven"] = "Пулемётная турель была выдана вам", ["aaTurretGiven"] = "ПВО была выдана вам", ["reloading"] = "ПЕРЕЗАРЯДКА...", ["targetLost"] = "ЦЕЛЬ ПОТЕРЯНА", ["targetAcquired"] = "ЦЕЛЬ ЗАХВАЧЕНА", ["acquiringTarget"] = "ЗАХВАТ ЦЕЛИ...", ["lockedOnTarget"] = "ЦЕЛЬ ЗАХВАЧЕНА", ["waitingForTarget"] = "ОЖИДАНИЕ ЦЕЛИ", ["manualSingle"] = "РУЧНОЙ (ОДИНОЧНЫЙ)", ["manualBurst"] = "РУЧНОЙ (ОЧЕРЕДЬ)", ["aaTurretIDIs"] = "ID турели - {0}", ["noAmmo"] = "НЕТ СНАРЯДОВ", ["irTrapStorage"] = "ИК-ЛОВУШКИ", ["noIRTraps"] = "У вас закончились ИК-ловушки", ["fire"] = "ВЫСТРЕЛ", ["changeMode"] = "ИЗМЕНИТЬ РЕЖИМ",
            }
            , this, "ru");
        }
        static string GetText(string textName, BasePlayer player) => Instance.lang.GetMessage(textName, Instance, player?.UserIDString);
#endregion
#region Harmony Boilerplate
        static Harmony harmonyInstance;
        void InitHarmony() {
            harmonyInstance = new Harmony($"ru.senyaa.{Name}");
            harmonyInstance.PatchAll();
        }
        void UnloadHarmony() {
            harmonyInstance.UnpatchAll();
        }
#endregion
#region Types
        public struct PositionData {
            public Vector3 Position;
            public Vector3 Direction;
            public PositionData(Vector3 position, Vector3 direction) {
                Position = position;
                Direction = direction;
            }
        }
        public sealed class AARocket : FacepunchBehaviour {
            public BaseEntity Target {
                get;
                set;
            }
            TimedExplosive explosive;
            void Awake() {
                explosive = GetComponent<TimedExplosive>();
                explosive.SetFuse(config.AATurret_Rocket_FuseLength);
                explosive.explosionRadius = config.AATurret_Rocket_ExplosionRadius;
                AARockets.Add(this);
            }
            void OnDestroy() {
                AARockets?.Remove(this);
            }
            void FixedUpdate() {
                if (Target == null || Target.IsDestroyed) {
                    return;
                }
                var direction = (Target.transform.position - transform.position).normalized;
                var lookRotation = Quaternion.LookRotation(direction);
                transform.rotation = Quaternion.Slerp(transform.rotation, lookRotation, 10f);
                if (Vector3.Distance(transform.position, Target.transform.position) <= config.AATurret_Rocket_ExplosionRadius) {
                    explosive.Explode();
                }
            }
        }
        public sealed class AATurret : FacepunchBehaviour, ISpawnable {
            public enum Modes {
                Automatic, Standby, Manual_single, Manual_burst
            }
            public BaseEntity Target {
                get;
                private set;
            }
            public bool IsManuallyPlaced {
                get;
                private set;
            }
            public string CCTV_ID {
                get;
                set;
            }
            public DroppedItemContainer AmmoStorage {
                get;
                private set;
            }
            public int AmmoItemID {
                get;
                private set;
            }
            public List<BasePlayer> CurrentlyControlling;
            CCTV_RC camera;
            BaseEntity pivotY;
            BaseEntity pivotX;
            BaseEntity spinner;
            List<BaseEntity> rocketLaunchers;
            int targetHits;
            Modes _mode;
            int currentLauncherID = 0;
            bool hasRecentlyFired;
            public Modes Mode {
                get {
                    return _mode;
                }
                set {
                    _mode = value;
                    targetHits = 0;
                    foreach (var player in CurrentlyControlling) {
                        DrawMode(player);
                        SendEffect("assets/prefabs/locks/keypad/effects/lock.code.unlock.prefab", player, camera.transform.position);
                    }
                }
            }
            public static Item CreateItem() {
                var item = ItemManager.CreateByItemID(SPINNER_ITEMID, 1, config.AATurret_Item_SkinID);
                item.name = config.AATurret_Item_Name;
                return item;
            }
            // ReSharper disable Unity.PerformanceAnalysis
            public static AATurret Spawn(Vector3 position, Quaternion rotation, string CCTV_ID = "", bool isManual = false, int ammoAmount = 0) {
                if (AATurrets.ContainsKey(CCTV_ID)) {
                    return null;
                }
                var spinner = GameManager.server.CreateEntity(SPINNER_PREFAB, position, rotation) as SpinnerWheel;
                UnityEngine.Object.DestroyImmediate(spinner.gameObject.GetComponent<DestroyOnGroundMissing>());
                if (isManual) {
                    Instance.NextFrame(() => {
                        if (spinner == null || spinner.IsDestroyed) {
                            return;
                        }
                        spinner.gameObject.AddComponent<DestroyOnGroundMissing>();
                    }
                    );
                }
                else {
                    IndestructibleEntities.Add(spinner);
                }
                AASpinners.Add(spinner);
                spinner.Spawn();
                spinner.EnableSaving(false);
                spinner.SetMaxHealth(config.AATurret_HP);
                spinner.SetHealth(config.AATurret_HP);
                var comp = spinner.gameObject.AddComponent<AATurret>();
                comp.IsManuallyPlaced = isManual;
                comp.Mode = Modes.Standby;
                if (CCTV_ID == "") {
                    while (true) {
                        var newId = "AATURRET" + UnityEngine.Random.Range(100, 10000).ToString();
                        if (!AATurrets.ContainsKey(newId)) {
                            comp.CCTV_ID += newId;
                            break;
                        }
                    }
                }
                else {
                    comp.CCTV_ID = CCTV_ID;
                }
                TurretEntities.Add(spinner);
                var nail = AttachWorldmodel(spinner, -2097376851, Vector3.zero, Quaternion.identity);
                comp.pivotY = nail;
                comp.spinner = spinner;
                AttachWorldmodel(nail, 95950017, new Vector3(-0.130317688f, 0.414741516f, -0.0435333252f), Quaternion.Euler(4.05267572f, 180f, 285.532654f));
                AttachWorldmodel(nail, 95950017, new Vector3(0.103477478f, 0.414741516f, -0.0435333252f), Quaternion.Euler(4.05267811f, 0, 285.532593f));
                AttachWorldmodel(nail, 95950017, new Vector3(0.0182723999f, 0.375617981f, 0.155380249f), Quaternion.Euler(0, 270f, 285.532654f));
                AttachWorldmodel(nail, -1673693549, new Vector3(-0.158760071f, 0.594429016f, -0.0280914307f), Quaternion.Euler(308.687531f, 246.939484f, 22.0384579f));
                TurretEntities.Add(AttachEntity(nail, "assets/prefabs/deployable/playerioents/tunnel/cabletunnel.prefab", new Vector3(0.107048035f, 0.56287384f, -0.127761841f), new Vector3(285.572113f, 303.333679f, 55.675457f)));
                TurretEntities.Add(AttachEntity(nail, "assets/prefabs/deployable/playerioents/gates/branch/electrical.branch.deployed.prefab", new Vector3(0.165611267f, 0.219795227f, -0.132400513f), new Vector3(358.176453f, 180.388336f, 177.677612f)));
                var pivotx = AttachWorldmodel(nail, -2097376851, new Vector3(-0.0199966431f, 0.858099997f, -0.0903000012f), Quaternion.Euler(0, 0, 180));
                comp.pivotX = pivotx;
                comp.camera = AttachEntity(pivotx, CCTV_PREFAB, new Vector3(-0.0358581543f, -0.214081705f, 0.157484442f), new Vector3(0, 0, 180f)) as CCTV_RC;
                comp.camera.rcIdentifier = comp.CCTV_ID;
                comp.camera.SendNetworkUpdateImmediate();
                TurretEntities.Add(comp.camera);
                comp.rocketLaunchers = new List<BaseEntity>();
                comp.rocketLaunchers.Add(AttachEntity(pivotx, ROCKET_LAUNCHER_PREFAB, new Vector3(0.0537109375f, -0.00244230032f, 0.159132391f), new Vector3(278.907288f, 40.0738029f, 357.223999f)));
                comp.rocketLaunchers.Add(AttachEntity(pivotx, ROCKET_LAUNCHER_PREFAB, new Vector3(0.189483643f, -0.00244230032f, 0.159132391f), new Vector3(278.907288f, 40.0738029f, 357.223999f)));
                comp.rocketLaunchers.Add(AttachEntity(pivotx, ROCKET_LAUNCHER_PREFAB, new Vector3(0.189483643f, 0.129210532f, 0.161268622f), new Vector3(278.907288f, 40.0738029f, 357.223999f)));
                comp.rocketLaunchers.Add(AttachEntity(pivotx, ROCKET_LAUNCHER_PREFAB, new Vector3(0.0537109375f, 0.129210532f, 0.161268622f), new Vector3(278.907288f, 40.0738029f, 357.223999f)));
                comp.rocketLaunchers.Add(AttachEntity(pivotx, ROCKET_LAUNCHER_PREFAB, new Vector3(-0.0769999996f, 0.129210532f, 0.161268622f), new Vector3(278.907288f, 40.0738029f, 357.223999f)));
                comp.rocketLaunchers.Add(AttachEntity(pivotx, ROCKET_LAUNCHER_PREFAB, new Vector3(-0.0769999996f, -0.00244230032f, 0.159132391f), new Vector3(278.907288f, 40.0738029f, 357.223999f)));
                AttachWorldmodel(pivotx, 596469572, new Vector3(0.249267578f, -0.0306710601f, 0.00263825804f), Quaternion.Euler(1.17321372f, 88.8424377f, 182.353027f));
                AttachWorldmodel(pivotx, 1882709339, new Vector3(0.225280762f, -0.0946664214f, 0.115065016f), Quaternion.Euler(270.607178f, 84.0603714f, 4.42901897f));
                AttachWorldmodel(pivotx, 1882709339, new Vector3(-0.265167236f, -0.0946664214f, 0.115065016f), Quaternion.Euler(272.126343f, 271.872528f, 177.131348f));
                AttachWorldmodel(pivotx, 1882709339, new Vector3(-0.0316467285f, -0.242188394f, 0.101149f), Quaternion.Euler(0, 90f, 179.111053f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.107055664f, -0.219910562f, 0.0945572034f), Quaternion.Euler(0, 90f, 179.625061f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.0217285156f, -0.21930021f, 0.0944961682f), Quaternion.Euler(0f, 90f, 179.625061f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.155487061f, 0.0394278169f, -0.203050226f), Quaternion.Euler(0f, 270f, 0.374949962f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.0701599121f, 0.0387869477f, -0.203111261f), Quaternion.Euler(0f, 270f, 0.374949962f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.103393555f, 0.0387869477f, -0.203111261f), Quaternion.Euler(0, 270f, 0.374949962f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.107055664f, -0.221833169f, -0.201280206f), Quaternion.Euler(0f, 90f, 179.625061f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.188110352f, -0.040009439f, -0.20274505f), Quaternion.Euler(270.374298f, 180f, 90f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.186889648f, -0.141205728f, -0.202195734f), Quaternion.Euler(270.374298f, 180f, 90f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.23828125f, -0.0395516753f, -0.20250091f), Quaternion.Euler(89.6257019f, -0.00130411517f, 89.9986954f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.239532471f, -0.140717447f, -0.201890558f), Quaternion.Euler(89.6257019f, -0.00130411517f, 89.9986954f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.0217285156f, -0.2211923f, -0.201219171f), Quaternion.Euler(0, 90f, 179.625061f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.151824951f, -0.2211923f, -0.201219171f), Quaternion.Euler(0, 90f, 179.625061f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.151824951f, -0.21930021f, 0.0944961682f), Quaternion.Euler(0, 90f, 179.625061f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.239532471f, -0.138794839f, 0.0940078869f), Quaternion.Euler(89.6257019f, -0.00130411517f, 89.9986954f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.23828125f, -0.0376290679f, 0.0933365002f), Quaternion.Euler(89.6257019f, -0.00130411517f, 89.9986954f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.186889648f, -0.139283121f, 0.0937637463f), Quaternion.Euler(270.374298f, 180f, 90f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.188110352f, -0.038056314f, 0.0930313244f), Quaternion.Euler(270.374298f, 180f, 90f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.103393555f, 0.0407095551f, 0.0929092541f), Quaternion.Euler(0, 270f, 0.374949962f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.0701599121f, 0.0407095551f, 0.0929092541f), Quaternion.Euler(0, 270f, 0.374949962f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.155487061f, 0.0413504243f, 0.0930313244f), Quaternion.Euler(0, 270f, 0.374949962f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.155487061f, 0.0435171723f, 0.428602606f), Quaternion.Euler(0, 270f, 0.374949962f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.0701599121f, 0.0429068208f, 0.428602606f), Quaternion.Euler(0, 270f, 0.374949962f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.103393555f, 0.0429068208f, 0.428602606f), Quaternion.Euler(0, 270f, 0.374949962f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.107055664f, -0.217713296f, 0.430250555f), Quaternion.Euler(0f, 90f, 179.625061f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.188110352f, -0.0358590484f, 0.428785712f), Quaternion.Euler(270.374298f, 180f, 90f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.186889648f, -0.137085855f, 0.429273993f), Quaternion.Euler(270.374298f, 180f, 90f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.23828125f, -0.0354318023f, 0.429151922f), Quaternion.Euler(89.6257019f, -0.00130411517f, 89.9986954f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.239532471f, -0.136597574f, 0.429579169f), Quaternion.Euler(89.6257019f, -0.00130411517f, 89.9986954f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(0.0217285156f, -0.217072427f, 0.430250555f), Quaternion.Euler(0, 90f, 179.625061f));
                AttachWorldmodel(pivotx, 317398316, new Vector3(-0.151824951f, -0.217072427f, 0.430250555f), Quaternion.Euler(0, 90, 179.625061f));
                if (!config.AATurret_InfiniteAmmo) {
                    var itemContainer = GameManager.server.CreateEntity(LOOTABLE_PREFAB, spinner.transform.position, spinner.transform.rotation) as DroppedItemContainer;
                    itemContainer.transform.localPosition = new Vector3(0, 0.1f, 0);
                    itemContainer.transform.localRotation = Quaternion.Euler(0, 0, 0);
                    itemContainer.SetParent(spinner);
                    UnityEngine.Object.DestroyImmediate(itemContainer.gameObject.GetComponent<Rigidbody>());
                    itemContainer.inventory = new ItemContainer();
                    itemContainer.inventory.ServerInitialize(null, 6);
                    itemContainer.inventory.GiveUID();
                    itemContainer.inventory.entityOwner = spinner;
                    itemContainer.inventory.SetFlag(ItemContainer.Flag.NoItemInput, false);
                    itemContainer.Spawn();
                    IndestructibleEntities.Add(itemContainer);
                    itemContainer.CancelInvoke(itemContainer.RemoveMe);
                    itemContainer.EnableSaving(false);
                    itemContainer.SendNetworkUpdateImmediate();
                    comp.AmmoStorage = itemContainer;
                    AATurretContainers.Add(itemContainer.inventory);
                    var ammoDef = ItemManager.FindItemDefinition(config.AATurret_AmmoShortname);
                    itemContainer.inventory.AddItem(ammoDef, ammoAmount);
                    comp.AmmoItemID = ammoDef.itemid;
                }
                comp.Invoke(() => {
                    if (comp?.rocketLaunchers == null) {
                        return;
                    }
                    foreach (var rocketLauncher in comp.rocketLaunchers) {
                        rocketLauncher.transform.localRotation = Quaternion.Euler(278.907288f, 40.0738029f, 357.223999f);
                        rocketLauncher.SendNetworkUpdate_Position();
                    }
                }
                , 0.15f);
                AATurrets.Add(comp.CCTV_ID, comp);
                comp.InvokeRepeating(comp.RefreshGunPosition, 0f, 5f);
                comp.InvokeRepeating(comp.UITick, 0f, config.AATurret_TargetAcquiringTime / 4f);
                return comp;
            }
            void Awake() {
                CurrentlyControlling = new List<BasePlayer>();
            }
            void OnDestroy() {
                foreach (var player in CurrentlyControlling) {
                    OnControlEnd(player, false);
                }
                OnKilled();
            }
            void FixedUpdate() {
                if (Mode == Modes.Automatic && (Target == null || Target.IsDestroyed)) {
                    LoseTarget();
                    return;
                }
                if (Target?.transform == null || Target.IsDestroyed) {
                    return;
                }
                var rotX = pivotX.transform.eulerAngles;
                pivotX.transform.LookAt(Target.transform);
                rotX.x = pivotX.transform.eulerAngles.x - camera.transform.localEulerAngles.x;
                pivotX.transform.eulerAngles = rotX;
                var rotY = pivotY.transform.eulerAngles;
                pivotY.transform.LookAt(Target.transform);
                rotY.y = pivotX.transform.eulerAngles.y;
                pivotY.transform.eulerAngles = rotY;
                pivotY.SendChildrenNetworkUpdateImmediate();
                pivotX.SendChildrenNetworkUpdateImmediate();
                spinner.SendChildrenNetworkUpdateImmediate();
            }
            void RefreshGunPosition() {
                if (spinner == null || spinner.IsDestroyed || rocketLaunchers == null) {
                    return;
                }
                foreach (var rocketLauncher in rocketLaunchers) {
                    rocketLauncher.SendNetworkUpdate_Position();
                }
            }
            void UITick() {
                if (CurrentlyControlling == null) {
                    return;
                }
                if (Mode == Modes.Manual_single || Mode == Modes.Manual_burst) {
                    return;
                }
                if (camera == null || camera.IsDestroyed) {
                    return;
                }
                if (Target != null && !Target.IsDestroyed) {
                    var dist = Vector3.Distance(camera.transform.position, Target.transform.position);
                    if (dist >= config.AATurret_MaxLockOnDistance) {
                        LoseTarget();
                        return;
                    }
                    foreach (var player in CurrentlyControlling) {
                        RedrawUI(player, dist);
                    }
                    return;
                }
                RaycastHit hit;
                if (Physics.Raycast(camera.transform.position, camera.transform.rotation * Vector3.forward, out hit, config.AATurret_MaxLockOnDistance)) {
                    var ent = hit.GetEntity();
                    if (ent != null && config.AATurret_AbleToLockOn.Contains(ent.ShortPrefabName)) {
                        targetHits++;
                        foreach (var player in CurrentlyControlling) {
                            DrawAcquiringTargetUI(player, targetHits / 4f);
                            DrawDefaultCrosshair(player, "0.55 0.78 0.24 0.8");
                            SendEffect(EFFECT_CODELOCK_LOCK, player, camera.transform.position);
                        }
                        if (targetHits > 3) {
                            LockTarget(ent);
                        }
                        return;
                    }
                }
                targetHits = 0;
                foreach (var player in CurrentlyControlling) {
                    DrawDefaultCrosshair(player);
                    CuiHelper.DestroyUi(player, ACQUIRING_TARGET_PARENT_CUI);
                    CuiHelper.DestroyUi(player, TARGET_DISTANCE_CUI);
                }
            }
            void OnKilled() {
                AATurrets?.Remove(CCTV_ID);
                CancelInvoke(RefreshGunPosition);
                CancelInvoke(UITick);
                CancelInvoke(FiringAction);
                if (pivotY != null && !pivotY.IsDestroyed) {
                    pivotY.AdminKill();
                }
                if (spinner != null && !spinner.IsDestroyed) {
                    spinner.AdminKill();
                }
                if (rocketLaunchers != null) {
                    Facepunch.Pool.FreeList(ref rocketLaunchers);
                }
            }
            public void RemoveColliders() {
                UnityEngine.Object.DestroyImmediate(camera.gameObject.GetComponent<MeshCollider>());
                UnityEngine.Object.DestroyImmediate(spinner.gameObject.GetComponent<MeshCollider>());
            }
            public BaseEntity GetEntity() => spinner;
            public void OnControlStart(BasePlayer player) {
                if (CurrentlyControlling.Contains(player)) {
                    return;
                }
                CurrentlyControlling.Add(player);
                DrawInitialUI(player);
            }
            public void OnControlEnd(BasePlayer player, bool deletePlayer = true) {
                if (!CurrentlyControlling.Contains(player)) {
                    return;
                }
                if (deletePlayer) {
                    CurrentlyControlling.Remove(player);
                }
                CuiHelper.DestroyUi(player, AA_TURRET_CUI);
            }
            public void ChangeMode() {
                switch (Mode) {
                    case Modes.Automatic : LoseTarget();
                    Mode = Modes.Standby;
                    break;
                    case Modes.Standby : foreach (var player in CurrentlyControlling) {
                        CuiHelper.DestroyUi(player, ACQUIRING_TARGET_PARENT_CUI);
                        CuiHelper.DestroyUi(player, LOCKED_UI_CUI);
                        DrawDefaultCrosshair(player);
                    }
                    Mode = Modes.Manual_single;
                    break;
                    case Modes.Manual_single : Mode = Modes.Manual_burst;
                    break;
                    case Modes.Manual_burst : Mode = Modes.Standby;
                    break;
                }
            }
            public void OnPlayerInput(BasePlayer player) {
                var inputState = player.serverInput;
                if (Target != null) {
                    return;
// ... [Code preview truncated due to length. Full source in attached file] ...

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