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

FREE RemoteTurrets : 0.2.48 0.2.48

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
 //Requires: RustNET
using System.Collections.Generic;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using UnityEngine;
using System.Linq;
using Network;
namespace Oxide.Plugins {
    [Info("RemoteTurrets", "k1lly0u", "0.2.48")]
    [Description("This plugin was fixed by Инкуб to order [Rust Plugin Sliv]: https://discord.gg/pFgKw6Dyyq")]
    class RemoteTurrets : RustPlugin {
#region Fields
        [PluginReference]
        Plugin RocketTurrets;
        private StoredData storedData;
        private DynamicConfigFile data;
        private static RemoteTurrets ins;
        private static LinkManager linkManager;
        private static int layerMask;
        private List<TurretManager> turretManagers = new List<TurretManager>();
        private bool wipeData;
        private bool isInitialized;
        const string setTurrets = "remoteturrets.set";
        const string RTUI_Overlay = "RTUI_Overlay";
#endregion
#region Oxide Hooks
        private void Loaded() {
            permission.RegisterPermission(setTurrets, this);
            foreach (string key in configData.Options.Permissions.Keys) {
                if (permission.PermissionExists(key, this)) continue;
                permission.RegisterPermission(key, this);
            }
            lang.RegisterMessages(Messages, this);
            data = Interface.Oxide.DataFileSystem.GetFile("RustNET/remoteturrets");
            linkManager = new LinkManager();
            layerMask = LayerMask.GetMask("Default", "Water", "Deployed", "AI", "Vehicle_Movement", "World", "Player_Server", "Construction", "Terrain", "Tree");
        }
        private void OnServerInitialized() {
            ins = this;
            LoadData();
            if (wipeData) {
                storedData = new StoredData();
                SaveData();
            }
            LoadDefaultImages();
            InvokeHandler.Invoke(ServerMgr.Instance, InitializeAllLinks, 10f);
            RustNET.RegisterModule(Title, this);
        }
        private void OnPlayerDisconnected(BasePlayer player) {
            Controller controller = player.GetComponent<Controller>();
            if (controller != null) {
                LinkManager.TurretLink link = linkManager.GetLinkOf(controller);
                if (link != null) link.CloseLink(controller);
            }
        }
        private object OnPlayerCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            if (player != null && player.GetComponent<Controller>()) return false;
            return null;
        }
        private object OnPlayerTick(BasePlayer player, PlayerTick msg, bool wasPlayerStalled) {
            Controller controller = player.GetComponent<Controller>();
            if (controller != null) return false;
            return null;
        }
        private void OnEntityKill(BaseNetworkable networkable) {
            if (networkable != null) linkManager.OnEntityDeath(networkable);
        }
        private object OnTurretShutdown(AutoTurret turret) => OnTurretInteractionGeneric(turret);
        private object OnTurretToggle(AutoTurret turret) => OnTurretInteractionGeneric(turret);
        private object OnTurretModeToggle(AutoTurret turret) => OnTurretInteractionGeneric(turret);
        private object OnTurretInteractionGeneric(AutoTurret turret) {
            TurretManager manager = turret.GetComponent<TurretManager>();
            if (manager != null && manager.isBeingUsed) return false;
            return null;
        }
        private void OnNewSave(string filename) => wipeData = true;
        private void OnServerSave() => SaveData();
        private void Unload() {
            if (InvokeHandler.IsInvoking(ServerMgr.Instance, InitializeAllLinks)) InvokeHandler.CancelInvoke(ServerMgr.Instance, InitializeAllLinks);
            if (isInitialized) SaveData();
            linkManager.DestroyAllLinks();
            foreach (BasePlayer player in BasePlayer.activePlayerList) CuiHelper.DestroyUi(player, RTUI_Overlay);
            ins = null;
            linkManager = null;
        }
#endregion
#region Functions
        private void InitializeAllLinks() {
            for (int i = storedData.registeredTurrets.Length - 1; i >= 0; i--) {
                TurretManager.TurretData turretData = storedData.registeredTurrets.ElementAt(i);
                NetworkableId networkableId = new NetworkableId(turretData.turretId);
                AutoTurret turret = BaseEntity.serverEntities.Find(networkableId) as AutoTurret;
                if (turret == null || !RustNET.linkManager.IsValidTerminal(turretData.terminalId)) continue;
                LinkManager.TurretLink link = linkManager.GetLinkOf(turretData.terminalId);
                if (link == null) link = new LinkManager.TurretLink(turretData.terminalId, turret, turretData.turretName);
                else link.AddTurretToLink(turret, turretData.turretName);
            }
            isInitialized = true;
        }
        private int GetMaxTurrets(ulong playerId) {
            int max = 0;
            foreach (KeyValuePair<string, int> entry in configData.Options.Permissions) {
                if (permission.UserHasPermission(playerId.ToString(), entry.Key)) {
                    if (max < entry.Value) max = entry.Value;
                }
            }
            return max;
        }
        private void OnRocketTurretCreated(AutoTurret turret) {
            TurretManager manager = turret?.GetComponent<TurretManager>();
            if (manager != null) {
                manager.CheckRocketTurret();
            }
        }
#endregion
#region RustNET Integration
        private void DestroyAllLinks() => linkManager.DestroyAllLinks();
        private void OnLinkShutdown(int terminalId) {
            LinkManager.TurretLink link = linkManager.GetLinkOf(terminalId);
            if (link != null) link.OnLinkTerminated(false);
        }
        private void OnLinkDestroyed(int terminalId) {
            LinkManager.TurretLink link = linkManager.GetLinkOf(terminalId);
            if (link != null) link.OnLinkTerminated(true);
        }
        private TurretManager[] GetAvailableTurrets(int terminalId) {
            LinkManager.TurretLink link = linkManager.GetLinkOf(terminalId);
            if (link != null) return link.managers.Where(x => x != null && x.turret != null && !x.turret.IsDestroyed).ToArray();
            return new TurretManager[0];
        }
        private bool IsEntityEnabled(int terminalId, ulong managerId) {
            LinkManager.TurretLink link = linkManager.GetLinkOf(terminalId);
            if (link != null) {
                TurretManager manager = link.managers.Find(x => x.turret.net.ID.Value == managerId);
                if (manager != null) return manager.IsEnabled();
            }
            return false;
        }
        private void InitializeController(BasePlayer player, ulong managerId, int terminalId) {
            LinkManager.TurretLink link = linkManager.GetLinkOf(terminalId);
            if (link != null) link.InitiateLink(player, managerId);
        }
        private void ToggleAutomation(ulong managerId, int terminalId, bool active) {
            LinkManager.TurretLink link = linkManager.GetLinkOf(terminalId);
            if (link != null) {
                TurretManager manager = link.managers.Find(x => x.turret.net.ID.Value == managerId);
                if (manager != null) manager.ToggleAutomation(active);
            }
        }
        private void OpenInventory(BasePlayer player, ulong managerId, int terminalId) {
            LinkManager.TurretLink link = linkManager.GetLinkOf(terminalId);
            if (link != null) {
                TurretManager manager = link.managers.Find(x => x.turret.net.ID.Value == managerId);
                if (manager != null) RustNET.OpenInventory(player, manager.turret, manager.turret.inventory);
            }
        }
        private string GetHelpString(ulong playerId, bool title) => title ? msg("UI.Help.Title", playerId) : msg("UI.Help", playerId);
        private bool AllowPublicAccess() => false;
#endregion
#region Components
        private class LinkManager {
            public List<TurretLink> links = new List<TurretLink>();
            public TurretLink GetLinkOf(TurretManager turret) => links.Find(x => x.managers.Contains(turret)) ?? null;
            public TurretLink GetLinkOf(Controller controller) => links.Find(x => x.controllers.Contains(controller)) ?? null;
            public TurretLink GetLinkOf(int terminalId) => links.Find(x => x.terminalId == terminalId) ?? null;
            public TurretLink GetLinkOf(AutoTurret turret) {
                TurretManager component = turret.GetComponent<TurretManager>();
                if (component == null) return null;
                return GetLinkOf(component);
            }
            public void OnEntityDeath(BaseNetworkable networkable) {
                for (int i = links.Count - 1; i >= 0; i--) links.ElementAt(i).OnEntityDeath(networkable);
            }
            public void DestroyAllLinks() {
                foreach (TurretLink link in links) link.OnLinkTerminated(false);
            }
            public class TurretLink {
                public int terminalId {
                    get;
                    private set;
                }
                public List<Controller> controllers {
                    get;
                    private set;
                }
                public List<TurretManager> managers {
                    get;
                    private set;
                }
                public TurretLink() {
                }
                public TurretLink(int terminalId, AutoTurret turret, string turretName) {
                    this.terminalId = terminalId;
                    this.controllers = new List<Controller>();
                    this.managers = new List<TurretManager>();
                    AddTurretToLink(turret, turretName);
                    linkManager.links.Add(this);
                }
                public void AddTurretToLink(AutoTurret turret, string turretName) {
                    TurretManager manager = turret.GetComponent<TurretManager>() ?? turret.gameObject.AddComponent<TurretManager>();
                    manager.turretName = turretName;
                    manager.terminalId = terminalId;
                    managers.Add(manager);
                    ins.turretManagers.Add(manager);
                }
                public void InitiateLink(BasePlayer player, ulong managerId) {
                    TurretManager manager = managers.FirstOrDefault(x => x.turret.net.ID.Value == managerId);
                    if (manager != null) {
                        player.inventory.crafting.CancelAll(true);
                        Controller controller = player.GetComponent<Controller>() ?? player.gameObject.AddComponent<Controller>();
                        controllers.Add(controller);
                        controller.InitiateLink(terminalId);
                        controller.SetTurretLink(this);
                        controller.SetSpectateTarget(managers.IndexOf(manager));
                    }
                }
                public void CloseLink(Controller controller, bool isDead = false) {
                    if (controller != null) {
                        controllers.Remove(controller);
                        controller.FinishSpectating(isDead);
                    }
                }
                public void OnEntityDeath(BaseNetworkable networkable) {
                    TurretManager manager = networkable.GetComponent<TurretManager>();
                    if (manager != null && managers.Contains(manager)) {
                        if (manager.controller != null) {
                            manager.controller.player.ChatMessage(ins.msg("Warning.TurretDestroyed", manager.controller.player.userID));
                            CloseLink(manager.controller);
                        }
                        ins.turretManagers.Remove(manager);
                        managers.Remove(manager);
                    }
                }
                public void OnLinkTerminated(bool isDestroyed) {
                    for (int i = controllers.Count - 1; i >= 0; i--) {
                        Controller controller = controllers.ElementAt(i);
                        controller.player.ChatMessage(isDestroyed ? ins.msg("Warning.TerminalDestroyed", controller.player.userID) : ins.msg("Warning.TerminalShutdown", controller.player.userID));
                        CloseLink(controller);
                    }
                    DestroyTurretManagers(isDestroyed);
                }
                private void DestroyTurretManagers(bool isDestroyed) {
                    foreach (TurretManager manager in managers) {
                        if (isDestroyed) ins.turretManagers.Remove(manager);
                        UnityEngine.Object.Destroy(manager);
                    }
                }
            }
        }
        private class Controller : RustNET.Controller {
            public TurretManager manager {
                get;
                private set;
            }
            private LinkManager.TurretLink link;
            private float nextShotTime;
            private int spectateIndex;
            private bool switchingTargets;
            private bool canCycle;
            public override void Awake() {
                base.Awake();
                enabled = false;
                canCycle = ins.configData.Remote.CanCycle;
            }
            private void Update() {
                if (player == null || player.serverInput == null || switchingTargets) return;
                InputState input = player.serverInput;
                if (manager != null && manager.controller == this) {
                    if (manager.IsPowered) {
                        manager.UpdateAimDirection(input);
                        if (input.WasJustPressed(BUTTON.FIRE_PRIMARY) || input.IsDown(BUTTON.FIRE_PRIMARY)) TryFireGun();
                    }
                }
                if (input.WasJustPressed(BUTTON.USE)) {
                    enabled = false;
                    link.CloseLink(this);
                }
                else {
                    if (canCycle) {
                        if (input.WasJustPressed(BUTTON.JUMP)) UpdateSpectateTarget(1);
                        else if (input.WasJustPressed(BUTTON.DUCK)) UpdateSpectateTarget(-1);
                    }
                }
            }
            public override void OnDestroy() {
                player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, false);
                player.SetPlayerFlag(BasePlayer.PlayerFlags.ThirdPersonViewmode, false);
                CuiHelper.DestroyUi(player, uiAmmo);
                base.OnDestroy();
            }
            private void TryFireGun() {
                if (manager.isRocketTurret) {
                    ins.RocketTurrets.Call("TryFireRocket", manager.turret);
                }
                else {
                    if (Time.realtimeSinceStartup >= nextShotTime) {
                        manager.turret.EnsureReloaded();
                        if (manager.turret.HasClipAmmo()) {
                            BaseProjectile attachedWeapon = manager.turret.GetAttachedWeapon();
                            if (attachedWeapon) {
                                manager.turret.FireAttachedGun(Vector3.zero, 0f);
                                ins.CreateAmmoUI(player, this);
                                float delay = 0;
                                if (attachedWeapon.primaryMagazine.contents <= 0) {
                                    delay = Mathf.Min(attachedWeapon.GetReloadDuration() * 0.5f, 2f);
                                    manager.turret.Reload();
                                    InvokeHandler.Invoke(this, () => ins.CreateAmmoUI(player, this), delay + 0.5f);
                                }
                                else delay = attachedWeapon.ScaleRepeatDelay((attachedWeapon.isSemiAuto ? attachedWeapon.repeatDelay * 1.5f : attachedWeapon.repeatDelay));
                                nextShotTime = Time.realtimeSinceStartup + delay;
                            }
                        }
                    }
                }
            }
            public void SetTurretLink(LinkManager.TurretLink link) {
                this.link = link;
                BeginSpectating();
            }
            public void SetSpectateTarget(int spectateIndex) {
                this.spectateIndex = spectateIndex;
                manager = link.managers[spectateIndex];
                RustNET.MovePosition(player, manager.turret.transform.position, false);
                if (manager.controller == null) {
                    manager.SetTurretStatus(true);
                    manager.SetController(this);
                    ins.CreateAmmoUI(player, this);
                }
                else player.ChatMessage(ins.msg("Warning.InUse", player.userID));
                CreateCameraOverlay();
            }
            public void UpdateSpectateTarget(int index = 0) {
                switchingTargets = true;
                player.Invoke(() => switchingTargets = false, 0.25f);
                int newIndex = spectateIndex + index;
                if (newIndex > link.managers.Count - 1) newIndex = 0;
                else if (newIndex < 0) newIndex = link.managers.Count - 1;
                if (spectateIndex == newIndex) return;
                if (manager.controller == this) {
                    manager.SetController(null);
                    manager.SetTurretStatus(false);
                }
                manager = null;
                SetSpectateTarget(newIndex);
            }
            public void BeginSpectating() {
                RustNET.StripInventory(player);
                player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, true);
                player.gameObject.SetLayerRecursive(10);
                player.CancelInvoke("InventoryUpdate");
                player.SetPlayerFlag(BasePlayer.PlayerFlags.ThirdPersonViewmode, true);
                NetWrite netWrite = Net.sv.StartWrite();
                netWrite.PacketID(Message.Type.EntityDestroy);
                netWrite.EntityID(player.net.ID);
                netWrite.UInt8((byte)BaseNetworkable.DestroyMode.None);
                netWrite.Send(new SendInfo(player.net.group.subscribers.Where(x => x.userid != player.userID).ToList()));
                if (canCycle) player.ChatMessage(ins.msg("Help.ControlInfo", player.userID));
                else player.ChatMessage(ins.msg("Help.ControlInfo.NoCycle", player.userID));
                enabled = true;
            }
            public void FinishSpectating(bool isDead) {
                enabled = false;
                player.SetPlayerFlag(BasePlayer.PlayerFlags.Spectating, false);
                player.gameObject.SetLayerRecursive(17);
                player.SetPlayerFlag(BasePlayer.PlayerFlags.ThirdPersonViewmode, false);
                player.InvokeRepeating("InventoryUpdate", 1f, 0.1f * UnityEngine.Random.Range(0.99f, 1.01f));
                player.Command("client.camoffset", new object[] {
                    new Vector3(0, 1.2f, 0)
                }
                );
                if (manager.controller == this) {
                    manager.SetController(null);
                    manager.SetTurretStatus(false);
                }
                CuiHelper.DestroyUi(player, uiAmmo);
                CuiHelper.DestroyUi(player, RTUI_Overlay);
                if (!isDead) Destroy(this);
            }
            public override void OnPlayerDeath(HitInfo info) {
                enabled = false;
                link.CloseLink(this, true);
                base.OnPlayerDeath(info);
            }
            private void CreateCameraOverlay() {
                if (!ins.configData.Remote.Overlay) return;
                CuiElementContainer container = RustNET.UI.Container("0 0 0 0", "0 0", "1 1", false, "Under", RTUI_Overlay);
                RustNET.UI.Image(ref container, ins.GetImage("turretoverlay"), "0 0", "1 1", RTUI_Overlay);
                RustNET.UI.Panel(ref container, "0 0 0 0.4", "0.82 0.9", "0.96 0.94", RTUI_Overlay);
                RustNET.UI.Label(ref container, string.IsNullOrEmpty(manager.turretName) ? string.Format(ins.msg("UI.TurretName", player.userID), spectateIndex + 1) : manager.turretName, 18, "0.82 0.9", "0.96 0.94", TextAnchor.MiddleCenter, RTUI_Overlay);
                CuiHelper.DestroyUi(player, RTUI_Overlay);
                CuiHelper.AddUi(player, container);
            }
        }
        private class TurretManager : MonoBehaviour {
            public AutoTurret turret {
                get;
                private set;
            }
            public Controller controller {
                get;
                private set;
            }
            //private Item ammoItem;
            public bool isBeingUsed {
                get;
                private set;
            }
            public bool isRocketTurret {
                get;
                private set;
            }
            public int terminalId {
                get;
                set;
            }
            public string turretName {
                get;
                set;
            }
            private bool wasOnline;
            private Vector3 targetPos = Vector3.zero;
            private Vector3 offset = new Vector3(0, 0.3f, 0);
            public bool IsPowered {
                get {
                    if (!ins.configData.Remote.RequirePower || (ins.configData.Remote.RequirePower && turret.IsPowered())) return true;
                    return false;
                }
            }
            private void Awake() {
                turret = GetComponent<AutoTurret>();
                enabled = false;
                CheckRocketTurret();
            }
            public void CheckRocketTurret() {
                isRocketTurret = false;
                if (ins.RocketTurrets) {
                    if ((bool)ins.RocketTurrets.Call("IsRocketTurret", turret)) {
                        isRocketTurret = true;
                        ins.RocketTurrets.Call("ToggleTurretAutomation", turret, false);
                    }
                }
            }
            private void OnDestroy() {
                if (turret != null && !turret.IsDestroyed) {
                    if (turret.IsOn()) {
                        if (turret.IsInvoking(ClientAimDirection)) turret.CancelInvoke(ClientAimDirection);
                        if (!turret.IsInvoking(turret.ServerTick)) turret.InvokeRepeating(turret.ServerTick, UnityEngine.Random.Range(0f, 1f), 0.015f);
                        if (!turret.IsInvoking(turret.SendAimDir)) turret.InvokeRandomized(turret.SendAimDir, UnityEngine.Random.Range(0f, 1f), 0.2f, 0.05f);
                        if (!turret.IsInvoking(turret.TargetScan)) turret.InvokeRandomized(turret.TargetScan, UnityEngine.Random.Range(0f, 1f), 1f, 0.1f);
                    }
                }
            }
            public void SetTurretStatus(bool status) {
                if (!status) {
                    if (turret.IsInvoking(ClientAimDirection)) turret.CancelInvoke(ClientAimDirection);
                    if (wasOnline && IsPowered) {
                        if (!turret.IsInvoking(turret.ServerTick)) turret.InvokeRepeating(turret.ServerTick, UnityEngine.Random.Range(0f, 1f), 0.015f);
                        if (!turret.IsInvoking(turret.SendAimDir)) turret.InvokeRandomized(turret.SendAimDir, UnityEngine.Random.Range(0f, 1f), 0.2f, 0.05f);
                        if (!turret.IsInvoking(turret.TargetScan)) turret.InvokeRandomized(turret.TargetScan, UnityEngine.Random.Range(0f, 1f), 1f, 0.1f);
                    }
                    else InvokeHandler.Invoke(this, TurretShutdown, 1f);
                }
                else {
                    wasOnline = turret.HasFlag(BaseEntity.Flags.On);
                    turret.enabled = false;
                    if (IsPowered) {
                        if (!turret.IsOnline() && !turret.booting) {
                            Effect.server.Run(turret.onlineSound.resourcePath, turret, 0, Vector3.zero, Vector3.zero, null, false);
                            turret.Invoke(SetIsOnline, 2f);
                            turret.booting = true;
                        }
                        else {
                            turret.CancelInvoke(turret.ServerTick);
                            turret.CancelInvoke(turret.SendAimDir);
                            turret.CancelInvoke(turret.TargetScan);
                            turret.InvokeRepeating(ClientAimDirection, 0f, 0.1f);
                        }
                    }
                }
            }
            private void TurretShutdown() {
                turret.CancelInvoke(turret.SetOnline);
                turret.booting = false;
                Effect.server.Run(turret.offlineSound.resourcePath, turret, 0, Vector3.zero, Vector3.zero, null, false);
                turret.SetFlag(BaseEntity.Flags.On, false, false, true);
                turret.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                turret.SetTarget(null);
                turret.isLootable = true;
            }
            private void SetIsOnline() {
                turret.SetFlag(BaseEntity.Flags.On, true, false, true);
                turret.booting = false;
                turret.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                turret.CancelInvoke(turret.ServerTick);
                turret.CancelInvoke(turret.SendAimDir);
                turret.CancelInvoke(turret.TargetScan);
                turret.InvokeRepeating(ClientAimDirection, 0f, 0.1f);
            }
            public void SetTurretAutomation(bool status) {
                if (status) {
                    if (!turret.IsInvoking(turret.ServerTick)) turret.InvokeRepeating(turret.ServerTick, UnityEngine.Random.Range(0f, 1f), 0.015f);
                    if (!turret.IsInvoking(turret.SendAimDir)) turret.InvokeRandomized(turret.SendAimDir, UnityEngine.Random.Range(0f, 1f), 0.2f, 0.05f);
                    if (!turret.IsInvoking(turret.TargetScan)) turret.InvokeRandomized(turret.TargetScan, UnityEngine.Random.Range(0f, 1f), 1f, 0.1f);
                    if (IsPowered) turret.InitiateStartup();
                }
                else TurretShutdown();
            }
            public void SetController(Controller controller) {
                isBeingUsed = controller != null;
                this.controller = controller;
            }
            public void UpdateAimDirection(InputState input) {
                RaycastHit hit;
                if (Physics.Raycast(new Ray(turret.muzzlePos.transform.position, Quaternion.Euler(input.current.aimAngles) * Vector3.forward), out hit, 500f, layerMask)) {
                    Vector3 targetPos = hit.point + offset;
                    Vector3 rotation = turret.gun_pitch.transform.InverseTransformPoint(turret.muzzlePos.transform.position);
                    rotation.x = 0;
                    rotation.z = 0;
                    Vector3 gunPitch = targetPos - (turret.gun_pitch.position + rotation);
                    turret.aimDir = gunPitch;
                    float dt = Time.deltaTime;
                    // Get the time delta
                    turret.UpdateAiming(dt);
                }
            }
            public bool IsEnabled() {
                if (controller == null) return turret.HasFlag(BaseEntity.Flags.On) || turret.IsInvoking(turret.SetOnline);
                else return wasOnline;
            }
            public void ToggleAutomation(bool active) {
                if (controller == null) SetTurretAutomation(active);
            }
            private void ClientAimDirection() => turret.ClientRPC(null, "CLIENT_ReceiveAimDir", turret.aimDir);
            public TurretData GetTurretData() => new TurretData(this);
            public class TurretData {
                public ulong turretId;
                public int terminalId;
                public string turretName;
                public TurretData() {
                }
                public TurretData(TurretManager manager) {
                    turretId = manager.turret.net.ID.Value;
                    terminalId = manager.terminalId;
                    turretName = manager.turretName;
                }
            }
        }
#endregion
#region UI
        const string uiAmmo = "RT.AmmoUI";
        private void CreateAmmoUI(BasePlayer player, Controller controller) {
            CuiElementContainer container = RustNET.UI.Container(RustNET.UI.Color("#F2F2F2", 0.05f), "0.69 0.1", "0.83 0.135", false, "Overlay", uiAmmo);
            string ammoAmount = string.Empty;
            BaseProjectile attachedWeapon = controller.manager.turret.GetAttachedWeapon();
            if (attachedWeapon != null) {
                int clipAmmo = attachedWeapon.primaryMagazine.contents;
                int storedAmmo = 0;
                List<Item> list = Facepunch.Pool.GetList<Item>();
                controller.manager.turret.inventory.FindAmmo(list, attachedWeapon.primaryMagazine.definition.ammoTypes);
                for (int i = 0; i < list.Count; i++) storedAmmo += list[i].amount;
                Facepunch.Pool.FreeList<Item>(ref list);
                ammoAmount = $"{clipAmmo} / {storedAmmo}";
            }
            else ammoAmount = "0 / 0";
            RustNET.UI.Label(ref container, string.Format(msg("UI.Ammo", player.userID), ammoAmount), 12, "0.03 0", "1 1", TextAnchor.MiddleLeft, uiAmmo);
            DestroyUI(player);
            CuiHelper.AddUi(player, container);
        }
        private void DestroyUI(BasePlayer player) => CuiHelper.DestroyUi(player, uiAmmo);
        private void CreateConsoleWindow(BasePlayer player, int terminalId, int page) {
            CuiElementContainer container = RustNET.ins.GetBaseContainer(player, terminalId, Title);
            TurretManager[] entityIds = GetAvailableTurrets(terminalId);
            RustNET.UI.Panel(ref container, RustNET.uiColors[RustNET.Colors.Panel], "0.04 0.765", "0.96 0.8");
            RustNET.UI.Label(ref container, msg("UI.Select.Turret", player.userID), 12, "0.05 0.765", "0.5 0.8", TextAnchor.MiddleLeft);
            RustNET.UI.Button(ref container, RustNET.uiColors[RustNET.Colors.Button], RustNET.msg("UI.MainMenu", player.userID), 11, "0.82 0.765", "0.96 0.8", $"rustnet.changepage {terminalId}");
            if (entityIds == null || entityIds.Length == 0) RustNET.UI.Label(ref container, msg("UI.NoTurrets", player.userID), 12, "0.05 0.5", "0.95 0.7");
            else {
                int count = 0;
                int startAt = page * 18;
                for (int i = startAt; i < (startAt + 18 > entityIds.Length ? entityIds.Length : startAt + 18);
                i++) {
                    TurretManager manager = entityIds.ElementAt(i);
                    RustNET.UI.Panel(ref container, RustNET.uiColors[RustNET.Colors.Panel], $"0.04 {(0.725f - (count * 0.04f))}", $"0.96 {(0.755f - (count * 0.04f))}");
                    RustNET.UI.Label(ref container, string.IsNullOrEmpty(manager.turretName) ? string.Format(msg("UI.Turret", player.userID), count + 1) : $"> {manager.turretName}", 11, $"0.05 {0.725f - (count * 0.04f)}", $"0.31 {0.755f - (count * 0.04f)}", TextAnchor.MiddleLeft);
                    if (configData.Remote.ToggleEnabled) {
                        bool isEnabled = manager.IsEnabled();
                        RustNET.UI.Button(ref container, RustNET.uiColors[RustNET.Colors.Button], isEnabled ? RustNET.msg("UI.Enable", player.userID) : RustNET.msg("UI.Disable", player.userID), 11, $"0.32 {0.725f - (count * 0.04f)}", $"0.53 {0.755f - (count * 0.04f)}", $"remoteturrets.toggle {manager.turret.net.ID} {terminalId} {page} {!isEnabled}");
                    }
                    if (configData.Remote.AccessInventory) RustNET.UI.Button(ref container, RustNET.uiColors[RustNET.Colors.Button], RustNET.msg("UI.Inventory", player.userID), 11, $"0.54 {0.725f - (count * 0.04f)}", $"0.75 {0.755f - (count * 0.04f)}", $"remoteturrets.inventory {manager.turret.net.ID} {terminalId}");
                    if (configData.Remote.RemoteControl) RustNET.UI.Button(ref container, RustNET.uiColors[RustNET.Colors.Button], RustNET.msg("UI.Control", player.userID), 11, $"0.76 {0.725f - (count * 0.04f)}", $"0.96 {0.755f - (count * 0.04f)}", $"remoteturrets.control {manager.turret.net.ID} {terminalId}");
                    count++;
                }
                int totalPages = entityIds.Length / 18;
                RustNET.UI.Button(ref container, RustNET.uiColors[RustNET.Colors.Button], RustNET.msg("UI.Back", player.userID), 11, "0.3 0.01", "0.44 0.04", page > 0 ? $"rustnet.changepage {terminalId} {Title} {page - 1}" : "");
                RustNET.UI.Label(ref container, string.Format(RustNET.msg("UI.Page", player.userID), page + 1, totalPages + 1), 11, "0.44 0.01", "0.56 0.04");
                RustNET.UI.Button(ref container, RustNET.uiColors[RustNET.Colors.Button], RustNET.msg("UI.Next", player.userID), 11, "0.56 0.01", "0.7 0.04", page + 1 <= totalPages ? $"rustnet.changepage {terminalId} {Title} {page + 1}" : "");
            }
            CuiHelper.DestroyUi(player, RustNET.RustNET_Panel);
            CuiHelper.AddUi(player, container);
        }
        [ConsoleCommand("remoteturrets.toggle")]
        private void ccmdToggle(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Connection.player as BasePlayer;
            if (player == null) return;
            if (!RustNET.linkManager.IsValidTerminal(arg.GetInt(1))) {
                CuiHelper.DestroyUi(player, RustNET.RustNET_Panel);
                SendReply(player, RustNET.msg("Warning.TerminalDestroyed", player.userID));
                return;
            }
            ToggleAutomation(arg.GetUInt(0), arg.GetInt(1), arg.GetBool(3));
            RustNET.ins.DisplayToPlayer(player, arg.GetInt(1), Title, arg.GetInt(2));
        }
        [ConsoleCommand("remoteturrets.inventory")]
        private void ccmdAccessInventory(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Connection.player as BasePlayer;
            if (player == null) return;
            CuiHelper.DestroyUi(player, RustNET.RustNET_Panel);
            OpenInventory(player, arg.GetUInt(0), arg.GetInt(1));
        }
        [ConsoleCommand("remoteturrets.control")]
        private void ccmdControl(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Connection.player as BasePlayer;
            if (player == null) return;
            if (!RustNET.linkManager.IsValidTerminal(arg.GetInt(1))) {
                CuiHelper.DestroyUi(player, RustNET.RustNET_Panel);
                SendReply(player, RustNET.msg("Warning.TerminalDestroyed", player.userID));
                return;
            }
            CuiHelper.DestroyUi(player, RustNET.RustNET_Panel);
            InitializeController(player, arg.GetUInt(0), arg.GetInt(1));
        }
#endregion
#region Commands
        [ChatCommand("rt")]
        void cmdRemote(BasePlayer player, string command, string[] args) {
            if (!permission.UserHasPermission(player.UserIDString, setTurrets)) return;
            if (args.Length == 0) {
                SendReply(player, $"<color=#ce422b>{Title}</color><color=#939393>  v{Version}  -</color> <color=#ce422b>{Author} @ www.chaoscode.io</color>");
                SendReply(player, msg("Help.Main", player.userID));
                SendReply(player, msg("Help.Add", player.userID));
                SendReply(player, msg("Help.Remove", player.userID));
                SendReply(player, msg("Help.Name", player.userID));
                return;
            }
            BaseEntity entity = RustNET.FindEntityFromRay(player);
            if (entity == null || !(entity is AutoTurret) || entity is NPCAutoTurret) {
                SendReply(player, msg("Error.InvalidEntity", player.userID));
                return;
            }
            if (!RustNET.IsFriendlyPlayer(entity.OwnerID, player.userID)) {
                SendReply(player, msg("Error.NotOwner", player.userID));
                return;
            }
            switch (args[0].ToLower()) {
                case "add" : {
                    if (args.Length < 2) {
                        SendReply(player, msg("Error.TerminalID", player.userID));
                        SendReply(player, msg("Help.Add", player.userID));
                        return;
                    }
                    if (entity.GetComponent<TurretManager>()) {
                        SendReply(player, msg("Error.AlreadyRegistered", player.userID));
                        return;
                    }
                    int terminalId;
                    if (!int.TryParse(args[1], out terminalId)) {
                        SendReply(player, msg("Error.TerminalID", player.userID));
                        return;
                    }
                    if (!RustNET.linkManager.IsValidTerminal(terminalId)) {
                        SendReply(player, msg("Error.RustNETID", player.userID));
                        return;
                    }
                    RustNET.LinkManager.Link link = RustNET.linkManager.GetLinkOf(terminalId);
                    if (link == null) {
                        SendReply(player, msg("Error.NoLink", player.userID));
                        return;
                    }
                    BuildingManager.Building building = link.terminal?.ParentEntity?.GetBuilding();
                    if (building == null) {
                        SendReply(player, msg("Error.NoBuilding", player.userID));
                        return;
                    }
                    if (!building.GetDominatingBuildingPrivilege().IsAuthed(player)) {
                        SendReply(player, msg("Error.NoPrivilege", player.userID));
                        return;
                    }
                    if (Vector3.Distance(entity.transform.position, link.terminal.DroppedItem.transform.position) > configData.Options.DistanceFromTerminal) {
                        SendReply(player, msg("Error.FarDistance", player.userID));
                        return;
                    }
                    LinkManager.TurretLink turretLink = linkManager.GetLinkOf(terminalId);
                    if (turretLink == null) turretLink = new LinkManager.TurretLink(terminalId, entity as AutoTurret, "");
                    else {
                        int turretLimit = GetMaxTurrets(player.userID);
                        if (turretLink.managers.Count >= turretLimit) {
                            SendReply(player, msg("Error.Limit", player.userID));
                            return;
                        }
                        turretLink.AddTurretToLink(entity as AutoTurret, "");
                    }
                    SendReply(player, msg("Success.Set", player.userID));
                    SaveData();
                }
                break;
                case "remove" : if (entity is AutoTurret) {
                    if (!entity.GetComponent<TurretManager>()) {
                        SendReply(player, msg("Error.NotRegisteredTurret", player.userID));
                        return;
                    }
                    LinkManager.TurretLink link = linkManager.GetLinkOf(entity as AutoTurret);
                    if (link == null) {
                        SendReply(player, msg("Error.NoLink", player.userID));
                        return;
                    }
                    TurretManager manager = entity.GetComponent<TurretManager>();
                    if (manager == null) {
                        SendReply(player, msg("Error.NoTurretComponent", player.userID));
                        return;
                    }
                    if (manager.controller != null) link.CloseLink(manager.controller);
                    link.managers.Remove(manager);
                    turretManagers.Remove(manager);
                    UnityEngine.Object.Destroy(manager);
                    SaveData();
                    SendReply(player, msg("Success.Remove", player.userID));
                    return;
                }
                return;
                case "name" : {
                    if (args.Length < 2) {
                        SendReply(player, msg("Error.NoNameSpecified", player.userID));
                        return;
                    }
                    TurretManager manager = RustNET.FindEntityFromRay(player)?.GetComponent<TurretManager>();
                    if (manager == null) {
                        SendReply(player, msg("Error.NoEntity", player.userID));
                        return;
                    }
                    manager.turretName = args[1];
                    SendReply(player, string.Format(msg("Success.NameSet", player.userID), args[1]));
                }
                return;
                default : SendReply(player, msg("Error.InvalidCommand", player.userID));
                break;
            }
        }
#endregion
#region Image Management
        private void LoadDefaultImages(int attempts = 0) {
            if (attempts > 3) {
                PrintError("ImageLibrary not found.Unable to load camera overlay UI");
                configData.Remote.Overlay = false;
                return;
            }
            if (configData.Remote.Overlay && !string.IsNullOrEmpty(configData.Remote.OverlayImage)) AddImage("turretoverlay", configData.Remote.OverlayImage);
            if (!string.IsNullOrEmpty(configData.Remote.RustNETIcon)) AddImage(Title, configData.Remote.RustNETIcon);
        }
        private void AddImage(string imageName, string fileName) => RustNET.ins.AddImage(imageName, fileName);
        private string GetImage(string name) => RustNET.ins.GetImage(name);
#endregion
#region Config
        private ConfigData configData;
        private class ConfigData {
            [JsonProperty(PropertyName = "Remote Settings")]
            public RemoteOptions Remote {
                get;
                set;
            }
            public OtherOptions Options {
                get;
                set;
            }
            public class RemoteOptions {
                [JsonProperty(PropertyName = "Allow players to cycle through all linked turrets")]
                public bool CanCycle {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Can players toggle turret automation")]
                public bool ToggleEnabled {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Can players control the turret remotely")]
                public bool RemoteControl {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Can players access the turret inventory")]
                public bool AccessInventory {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Require power to access the turret")]
                public bool RequirePower {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Display camera overlay UI")]
                public bool Overlay {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Camera overlay image URL")]
                public string OverlayImage {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Turret icon URL for RustNET menu")]
                public string RustNETIcon {
                    get;
                    set;
                }
            }
            public class OtherOptions {
                [JsonProperty(PropertyName = "Maximum distance a turret controller can be set away from the terminal")]
                public float DistanceFromTerminal {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Max placeable turrets using permission")]
                public Dictionary<string, int> Permissions {
                    get;
                    set;
                }
            }
            public class TurretOptions {
                [JsonProperty(PropertyName = "Turret Settings")]
                public TurretSettings Turret {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Maximum turrets allowed per base")]
                public int Max {
                    get;
                    set;
                }
                public class TurretSettings {
                    [JsonProperty(PropertyName = "Fire Rate - Time between shots in seconds")]
                    public float FireRate {
                        get;
                        set;
                    }
                    [JsonProperty(PropertyName = "Aim Cone (Accuracy)")]
                    public float AimCone {
                        get;
                        set;
                    }
                }
            }
            public Oxide.Core.VersionNumber Version {
                get;
                set;
            }
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            configData = Config.ReadObject<ConfigData>();
            if (configData.Version < Version) UpdateConfigValues();
            Config.WriteObject(configData, true);
        }
        protected override void LoadDefaultConfig() => configData = GetBaseConfig();
        private ConfigData GetBaseConfig() {
            return new ConfigData {
                Options = new ConfigData.OtherOptions {
                    DistanceFromTerminal = 50f, Permissions = new Dictionary<string, int> {
                        ["remoteturrets.set"]
                        = 4, ["remoteturrets.pro"] = 10,
                    }
                }
                , Remote = new ConfigData.RemoteOptions {
                    AccessInventory = true, CanCycle = true, RemoteControl = true, ToggleEnabled = true, OverlayImage = "http://www.rustedit.io/images/RustNET/turretoverlay.png", Overlay = true, RustNETIcon = "http://www.rustedit.io/images/RustNET/turreticon.png", RequirePower = true
                }
                , Version = Version
            }
            ;
        }
        protected override void SaveConfig() => Config.WriteObject(configData, true);
        private void UpdateConfigValues() {
            PrintWarning("Config update detected! Updating config values...");
            ConfigData baseConfig = GetBaseConfig();
           
// ... [Code preview truncated due to length. Full source in attached file] ...

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