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

FREE LustyMap : 2.1.2 2.1.2

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
 // Requires: ImageLibrary
// Reference: System.Drawing
using System;
using System.Text;
using System.Collections.Generic;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Game.Rust.Cui;
using Oxide.Core.Plugins;
using UnityEngine;
using System.Linq;
using System.Globalization;
using System.IO;
using System.Drawing;
namespace Oxide.Plugins {
    [Info("LustyMap", "Kayzor / k1lly0u", "2.1.2", ResourceId = 1333)]
    class LustyMap : RustPlugin {
#region Fields
        [PluginReference]
        Plugin Clans, EventManager, Friends;
        [PluginReference]
        ImageLibrary ImageLibrary;
        static MapSplitter mapSplitter;
        static LustyMap instance;
        static float mapSize;
        static string mapSeed;
        static string worldSize;
        static string level;
        private bool activated;
        private bool isNewSave;
        private bool isRustFriends;
        MarkerData storedMarkers;
        private DynamicConfigFile markerData;
        private Dictionary<string, MapUser> mapUsers;
        private List<MapMarker> staticMarkers;
        private Dictionary<string, MapMarker> customMarkers;
        private Dictionary<string, MapMarker> temporaryMarkers;
        private Dictionary<uint, ActiveEntity> entityMarkers;
        private Dictionary<string, List<string>> clanData;
        static string dataDirectory = $"file://{Interface.Oxide.DataDirectory}{Path.DirectorySeparatorChar}LustyMap{Path.DirectorySeparatorChar}";
#endregion
#region User Class
        class MapUser : MonoBehaviour {
            private Dictionary<string, List<string>> friends;
            public HashSet<string> friendList;
            public BasePlayer player;
            public MapMode mode;
            public MapMode lastMode;
            private MapMarker marker;
            private int mapX;
            private int mapZ;
            private int currentX;
            private int currentZ;
            private int mapZoom;
            private bool mapOpen;
            private bool inEvent;
            private bool adminMode;
            private int changeCount;
            private double lastChange;
            private bool isBlocked;
            private SpamOptions spam;
            private bool afkDisabled;
            private int lastMoveTime;
            private float lastX;
            private float lastZ;
            void Awake() {
                player = GetComponent<BasePlayer>();
                friends = new Dictionary<string, List<string>> {
                    {
                        "Clans", new List<string>()
                    }
                    , {
                        "FriendsAPI", new List<string>()
                    }
                }
                ;
                friendList = new HashSet<string>();
                spam = instance.configData.SpamOptions;
                inEvent = false;
                mapOpen = false;
                afkDisabled = false;
                enabled = false;
                mode = MapMode.None;
                lastMode = MapMode.None;
                adminMode = false;
                InvokeHandler.InvokeRepeating(this, UpdateMarker, 0.1f, 1f);
            }
            void OnDestroy() {
                InvokeHandler.CancelInvoke(this, UpdateMarker);
                InvokeHandler.CancelInvoke(this, UpdateMap);
                DestroyUI();
            }
            public void InitializeComponent() {
                if (MapSettings.friends) {
                    FillFriendList();
                }
                if (!instance.configData.MapOptions.StartOpen) {
                    ToggleMapType(MapMode.None);
                    return;
                }
                if (MapSettings.complexmap) {
                    mapZoom = 1;
                    ToggleMapType(MapMode.Complex);
                    if (MapSettings.forcedzoom) mapZoom = MapSettings.zoomlevel;
                }
                else if (MapSettings.minimap) {
                    mode = MapMode.Minimap;
                    ToggleMapType(mode);
                }
            }
#region Friends
            private void FillFriendList() {
                if (instance.configData.FriendOptions.UseClans) {
                    var clanTag = instance.GetClan(player.userID);
                    if (!string.IsNullOrEmpty(clanTag) && instance.clanData.ContainsKey(clanTag)) friends["Clans"] = instance.clanData[clanTag];
                }
                if (instance.configData.FriendOptions.UseFriends) friends["FriendsAPI"] = instance.GetFriends(player.userID);
                UpdateMembers();
            }
            private void UpdateMembers() {
                friendList.Clear();
                foreach (var list in friends) {
                    foreach (var member in list.Value) friendList.Add(member);
                }
            }
#endregion
#region Maps
            public float Rotation() => GetDirection(player?.transform?.rotation.eulerAngles.y ?? 0);
            public int Position(bool x) => x ? mapX : mapZ;
            public void Position(bool x, int pos) {
                if (x) mapX = pos;
                else mapZ = pos;
            }
            public void ToggleMapType(MapMode mapMode) {
                if (isBlocked || IsSpam()) return;
                DestroyUI();
                if (mapMode == MapMode.None) {
                    InvokeHandler.CancelInvoke(this, UpdateMap);
                    mode = MapMode.None;
                    mapOpen = false;
                    if (MapSettings.minimap) instance.CreateShrunkUI(player);
                }
                else {
                    mapOpen = true;
                    switch (mapMode) {
                        case MapMode.Main : mode = MapMode.Main;
                        instance.OpenMainMap(player);
                        break;
                        case MapMode.Complex : mode = MapMode.Complex;
                        instance.OpenComplexMap(player);
                        break;
                        case MapMode.Minimap : mode = MapMode.Minimap;
                        instance.OpenMiniMap(player);
                        break;
                    }
                    if (!IsInvoking("UpdateMap")) InvokeHandler.InvokeRepeating(this, UpdateMap, 0.1f, instance.configData.MapOptions.UpdateSpeed);
                }
            }
            public void UpdateMap() {
                switch (mode) {
                    case MapMode.None : break;
                    case MapMode.Main : instance.UpdateOverlay(player, LustyUI.MainOverlay, LustyUI.MainMin, LustyUI.MainMax, 0.01f);
                    break;
                    case MapMode.Complex : CheckForChange();
                    instance.UpdateCompOverlay(player);
                    break;
                    case MapMode.Minimap : instance.UpdateOverlay(player, LustyUI.MiniOverlay, LustyUI.MiniMin, LustyUI.MiniMax, 0.03f);
                    break;
                }
            }
#endregion
#region Complex
            public bool HasMapOpen() => (mapOpen && mode == MapMode.Main);
            public int Zoom() => mapZoom;
            public void Zoom(bool zoomIn) {
                var zoom = mapZoom;
                if (zoomIn) {
                    if (zoom < 3) zoom++;
                    else return;
                }
                else {
                    if (zoom > 0) zoom--;
                    else return;
                }
                InvokeHandler.CancelInvoke(this, UpdateMap);
                SwitchZoom(zoom);
            }
            private void SwitchZoom(int zoom) {
                if (zoom == 0 && MapSettings.minimap) {
                    mapZoom = zoom;
                    ToggleMapType(MapMode.Minimap);
                }
                else {
                    if (zoom == 0 && !MapSettings.minimap) zoom = 1;
                    mapZoom = zoom;
                    currentX = 0;
                    currentZ = 0;
                    ToggleMapType(MapMode.Complex);
                }
            }
            public int Current(bool x) => x ? currentX : currentZ;
            public void Current(bool x, int num) {
                if (x) currentX = num;
                else currentZ = num;
            }
            private void CheckForChange() {
                var mapSlices = ZoomToCount(mapZoom);
                float x = player.transform.position.x + mapSize / 2f;
                float z = player.transform.position.z + mapSize / 2f;
                var mapres = mapSize / mapSlices;
                var newX = Convert.ToInt32(Math.Ceiling(x / mapres)) - 1;
                var newZ = mapSlices - Convert.ToInt32(Math.Ceiling(z / mapres));
                if (currentX != newX || currentZ != newZ) {
                    DestroyUI();
                    currentX = newX;
                    currentZ = newZ;
                    instance.OpenComplexMap(player);
                }
            }
#endregion
#region Spam Checking
            private bool IsSpam() {
                if (!spam.Enabled) return false;
                changeCount++;
                var current = GrabCurrentTime();
                if (current - lastChange < spam.TimeBetweenAttempts) {
                    lastChange = current;
                    if (changeCount > spam.WarningAttempts && changeCount < spam.DisableAttempts) {
                        instance.SendReply(player, instance.msg("spamWarning", player.UserIDString));
                        return false;
                    }
                    if (changeCount >= spam.DisableAttempts) {
                        instance.SendReply(player, string.Format(instance.msg("spamDisable", player.UserIDString), spam.DisableSeconds));
                        Block();
                        Invoke("Unblock", spam.DisableSeconds);
                        return true;
                    }
                }
                else {
                    lastChange = current;
                    changeCount = 0;
                }
                return false;
            }
            private void Block() {
                isBlocked = true;
                OnDestroy();
            }
            private void Unblock() {
                isBlocked = false;
                ToggleMapType(lastMode);
                instance.SendReply(player, instance.msg("spamEnable", player.UserIDString));
            }
#endregion
#region Other
            public bool InEvent() => inEvent;
            public bool IsAdmin => adminMode;
            public void ToggleEvent(bool isPlaying) => inEvent = isPlaying;
            public void ToggleAdmin(bool enabled) => adminMode = enabled;
            public void DestroyUI() => LustyUI.DestroyUI(player);
            private void UpdateMarker() {
                var currentX = (float)Math.Round(transform.position.x, 1);
                var currentZ = (float)Math.Round(transform.position.z, 1);
                marker = new MapMarker {
                    name = RemoveSpecialCharacters(player.displayName), r = GetDirection(player?.eyes?.rotation.eulerAngles.y ?? 0), x = GetPosition(transform.position.x), z = GetPosition(transform.position.z)
                }
                ;
                if (instance.configData.MapOptions.EnableAFKTracking) {
                    if (lastX == currentX && lastZ == currentZ) ++lastMoveTime;
                    else {
                        lastX = currentX;
                        lastZ = currentZ;
                        lastMoveTime = 0;
                        if (afkDisabled) {
                            afkDisabled = false;
                            EnableUser();
                        }
                    }
                    if (lastMoveTime == 90) {
                        afkDisabled = true;
                        DisableUser();
                    }
                }
            }
            public MapMarker GetMarker() => marker;
            public void ToggleMain() {
                if (HasMapOpen()) {
                    if (MapSettings.minimap) {
                        if (Zoom() > 0) ToggleMapType(MapMode.Complex);
                        else ToggleMapType(MapMode.Minimap);
                    }
                    else ToggleMapType(MapMode.None);
                }
                else {
                    lastMode = mode;
                    CuiHelper.DestroyUi(player, LustyUI.Buttons);
                    ToggleMapType(MapMode.Main);
                }
            }
            public void DisableUser() {
                if (!mapOpen) return;
                InvokeHandler.CancelInvoke(this, UpdateMap);
                CuiHelper.DestroyUi(player, LustyUI.Buttons);
                if (mode != MapMode.None) LustyUI.DestroyUI(player);
                mapOpen = false;
            }
            public void EnableUser() {
                if (mapOpen) return;
                ToggleMapType(mode);
            }
            public void EnterEvent() => inEvent = true;
            public void ExitEvent() => inEvent = false;
#region Friends
            public bool HasFriendList(string name) => friends.ContainsKey(name);
            public void AddFriendList(string name, List<string> friendlist) {
                friends.Add(name, friendlist);
                UpdateMembers();
            }
            public void RemoveFriendList(string name) {
                friends.Remove(name);
                UpdateMembers();
            }
            public void UpdateFriendList(string name, List<string> friendlist) {
                friends[name] = friendlist;
                UpdateMembers();
            }
            public bool HasFriend(string name, string friendId) => friends[name].Contains(friendId);
            public void AddFriend(string name, string friendId) {
                friends[name].Add(friendId);
                UpdateMembers();
            }
            public void RemoveFriend(string name, string friendId) {
                friends[name].Remove(friendId);
                UpdateMembers();
            }
#endregion
#endregion
        }
        MapUser GetUser(BasePlayer player) => player.GetComponent<MapUser>() ?? null;
        MapUser GetUserByID(string playerId) => mapUsers.ContainsKey(playerId) ? mapUsers[playerId] : null;
#endregion
#region Markers
        class ActiveEntity : MonoBehaviour {
            public BaseEntity entity;
            private MapMarker marker;
            public AEType type;
            private string icon;
            void Awake() {
                entity = GetComponent<BaseEntity>();
                marker = new MapMarker();
                enabled = false;
            }
            void OnDestroy() {
                InvokeHandler.CancelInvoke(this, UpdatePosition);
            }
            public void SetType(AEType type) {
                this.type = type;
                switch (type) {
                    case AEType.None : break;
                    case AEType.Plane : icon = "plane";
                    marker.name = instance.msg("Plane");
                    break;
                    case AEType.SupplyDrop : icon = "supply";
                    marker.name = instance.msg("Supply Drop");
                    break;
                    case AEType.Helicopter : icon = "heli";
                    marker.name = instance.msg("Helicopter");
                    break;
                    case AEType.Debris : icon = "debris";
                    marker.name = instance.msg("Debris");
                    break;
                    case AEType.Vending : icon = "vending";
                    marker.name = instance.msg("Vending");
                    break;
                }
                InvokeHandler.InvokeRepeating(this, UpdatePosition, 0.1f, 1f);
            }
            public MapMarker GetMarker() => marker;
            void UpdatePosition() {
                if (type == AEType.Helicopter || type == AEType.Plane) {
                    marker.r = GetDirection(entity?.transform?.rotation.eulerAngles.y ?? 0);
                    marker.icon = $"{icon}{marker.r}";
                }
                else marker.icon = $"{icon}";
                marker.x = GetPosition(entity.transform.position.x);
                marker.z = GetPosition(entity.transform.position.z);
                if (type == AEType.Vending || type == AEType.SupplyDrop || type == AEType.Debris) InvokeHandler.CancelInvoke(this, UpdatePosition);
            }
        }
        class MapMarker {
            public string name {
                get;
                set;
            }
            public float x {
                get;
                set;
            }
            public float z {
                get;
                set;
            }
            public float r {
                get;
                set;
            }
            public string icon {
                get;
                set;
            }
        }
        static class MapSettings {
            static public bool minimap, complexmap, monuments, names, compass, caves, plane, heli, supply, debris, player, allplayers, friends, vending, forcedzoom;
            static public int zoomlevel;
        }
        public enum MapMode {
            None, Main, Complex, Minimap
        }
        enum AEType {
            None, Plane, SupplyDrop, Helicopter, Debris, Vending
        }
#endregion
#region UI
        class LMUI {
            static public CuiElementContainer CreateElementContainer(string panelName, string color, string aMin, string aMax, bool cursor = false, string parent = "Hud") {
                var NewElement = new CuiElementContainer() {
                    {
                        new CuiPanel {
                            Image = {
                                Color = color
                            }
                            , RectTransform = {
                                AnchorMin = aMin, AnchorMax = aMax
                            }
                            , CursorEnabled = cursor
                        }
                        , new CuiElement().Parent = parent, panelName
                    }
                }
                ;
                return NewElement;
            }
            static public void CreatePanel(ref CuiElementContainer container, string panel, string color, string aMin, string aMax, bool cursor = false) {
                container.Add(new CuiPanel {
                    Image = {
                        Color = color
                    }
                    , RectTransform = {
                        AnchorMin = aMin, AnchorMax = aMax
                    }
                    , CursorEnabled = cursor
                }
                , panel, CuiHelper.GetGuid());
            }
            static public void CreateLabel(ref CuiElementContainer container, string panel, string color, string text, int size, string aMin, string aMax, TextAnchor align = TextAnchor.MiddleCenter) {
                container.Add(new CuiLabel {
                    Text = {
                        Color = color, FontSize = size, Align = align, FadeIn = 0, Text = text
                    }
                    , RectTransform = {
                        AnchorMin = aMin, AnchorMax = aMax
                    }
                }
                , panel, CuiHelper.GetGuid());
            }
            static public void CreateButton(ref CuiElementContainer container, string panel, string color, string text, int size, string aMin, string aMax, string command, TextAnchor align = TextAnchor.MiddleCenter) {
                container.Add(new CuiButton {
                    Button = {
                        Color = color, Command = command, FadeIn = 0
                    }
                    , RectTransform = {
                        AnchorMin = aMin, AnchorMax = aMax
                    }
                    , Text = {
                        Text = text, FontSize = size, Align = align
                    }
                }
                , panel, CuiHelper.GetGuid());
            }
            static public void LoadImage(ref CuiElementContainer container, string panel, string png, string aMin, string aMax) {
                container.Add(new CuiElement {
                    Name = CuiHelper.GetGuid(), Parent = panel, Components = {
                        new CuiRawImageComponent {
                            Png = png, Sprite = "assets/content/textures/generic/fulltransparent.tga"
                        }
                        , new CuiRectTransformComponent {
                            AnchorMin = aMin, AnchorMax = aMax
                        }
                    }
                }
                );
            }
        }
#endregion
#region Oxide Hooks
        void OnNewSave(string filename) {
            isNewSave = true;
        }
        void Loaded() {
            markerData = Interface.Oxide.DataFileSystem.GetFile($"LustyMap{Path.DirectorySeparatorChar}CustomData");
            mapUsers = new Dictionary<string, MapUser>();
            staticMarkers = new List<MapMarker>();
            customMarkers = new Dictionary<string, MapMarker>();
            temporaryMarkers = new Dictionary<string, MapMarker>();
            entityMarkers = new Dictionary<uint, ActiveEntity>();
            clanData = new Dictionary<string, List<string>>();
            lang.RegisterMessages(Messages, this);
            permission.RegisterPermission("lustymap.admin", this);
        }
        void OnServerInitialized() {
            instance = this;
            worldSize = ConVar.Server.worldsize.ToString();
            mapSeed = ConVar.Server.seed.ToString();
            level = ConVar.Server.level;
            mapSize = TerrainMeta.Size.x;
            mapSplitter = new MapSplitter();
            LoadVariables();
            LoadData();
            LoadSettings();
            FindStaticMarkers();
            FindVendingMachines();
            ValidateImages();
            CheckFriends();
            GetClans();
        }
        void OnPlayerInit(BasePlayer player) {
            if (player == null) return;
            if (player.HasPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot) || player.IsSleeping()) {
                timer.In(2, () => OnPlayerInit(player));
                return;
            }
            if (activated) {
                var user = GetUser(player);
                if (user != null) {
                    UnityEngine.Object.DestroyImmediate(user);
                    if (mapUsers.ContainsKey(player.UserIDString)) mapUsers.Remove(player.UserIDString);
                }
                var mapUser = player.gameObject.AddComponent<MapUser>();
                if (!mapUsers.ContainsKey(player.UserIDString)) mapUsers.Add(player.UserIDString, mapUser);
                mapUser.InitializeComponent();
            }
        }
        void OnPlayerDisconnected(BasePlayer player) {
            if (player == null) return;
            if (mapUsers.ContainsKey(player.UserIDString)) {
                UnityEngine.Object.Destroy(mapUsers[player.UserIDString]);
                mapUsers.Remove(player.UserIDString);
            }
            LustyUI.DestroyUI(player);
        }
        void OnEntitySpawned(BaseEntity entity) {
            if (!activated) return;
            if (entity == null) return;
            if (entity is CargoPlane || entity is SupplyDrop || entity is BaseHelicopter || entity is HelicopterDebris || entity is VendingMachine) AddTemporaryEntityMarker(entity);
        }
        void OnEntityKill(BaseNetworkable entity) {
            var activeEntity = entity?.GetComponent<ActiveEntity>();
            if (activeEntity == null) return;
            if (entity?.net?.ID == null) return;
            if (entityMarkers.ContainsKey(entity.net.ID)) entityMarkers.Remove(entity.net.ID);
            UnityEngine.Object.Destroy(activeEntity);
        }
        void Unload() {
            foreach (var player in BasePlayer.activePlayerList) OnPlayerDisconnected(player);
            var mapUsers = UnityEngine.Object.FindObjectsOfType<MapUser>();
            if (mapUsers != null) foreach (var user in mapUsers) UnityEngine.Object.DestroyImmediate(user);
            var tempMarkers = UnityEngine.Object.FindObjectsOfType<ActiveEntity>();
            if (tempMarkers != null) foreach (var marker in tempMarkers) UnityEngine.Object.DestroyImmediate(marker);
        }
#endregion
#region Static UI Generation
        static class LustyUI {
            public static string Main = "LMUI_MapMain";
            public static string Mini = "LMUI_MapMini";
            public static string Complex = "LMUI_Complex";
            public static string MainOverlay = "LMUI_MainOverlay";
            public static string MiniOverlay = "LMUI_MiniOverlay";
            public static string ComplexOverlay = "LMUI_ComplexOverlay";
            public static string Buttons = "LMUI_Buttons";
            public static string MainMin;
            public static string MainMax;
            public static string MiniMin;
            public static string MiniMax;
            public static CuiElementContainer StaticMain;
            public static CuiElementContainer StaticMini;
            public static Dictionary<int, CuiElementContainer[, ]> StaticComplex = new Dictionary<int, CuiElementContainer[, ]>();
            private static Dictionary<ulong, List<string>> OpenUI = new Dictionary<ulong, List<string>>();
            public static void RenameComponents() {
                if (StaticMain != null) {
                    foreach (var element in StaticMain) {
                        if (element.Name == "AddUI CreatedPanel") element.Name = CuiHelper.GetGuid();
                    }
                }
                if (StaticMini != null) {
                    foreach (var element in StaticMini) {
                        if (element.Name == "AddUI CreatedPanel") element.Name = CuiHelper.GetGuid();
                    }
                }
                if (StaticComplex != null) {
                    foreach (var size in StaticComplex) {
                        foreach (var piece in size.Value) {
                            foreach (var element in piece) {
                                if (element.Name == "AddUI CreatedPanel") element.Name = CuiHelper.GetGuid();
                            }
                        }
                    }
                }
                instance.activated = true;
                if (instance.configData.MapOptions.StartOpen) instance.ActivateMaps();
            }
            public static void AddBaseUI(BasePlayer player, MapMode type) {
                try {
                    var user = instance.GetUser(player);
                    if (user == null) return;
                    DestroyUI(player);
                    CuiElementContainer element = null;
                    switch (type) {
                        case MapMode.None : return;
                        case MapMode.Main : element = StaticMain;
                        CuiHelper.AddUi(player, StaticMain);
                        AddElementIds(player, ref element);
                        return;
                        case MapMode.Complex : element = StaticComplex[(MapSettings.forcedzoom ? MapSettings.zoomlevel : user.Zoom())][user.Current(true), user.Current(false)];
                        instance.AddMapButtons(player);
                        CuiHelper.AddUi(player, element);
                        AddElementIds(player, ref element);
                        return;
                        case MapMode.Minimap : element = StaticMini;
                        instance.AddMapButtons(player);
                        CuiHelper.AddUi(player, element);
                        AddElementIds(player, ref element);
                        return;
                    }
                }
                catch {
                }
            }
            private static void AddElementIds(BasePlayer player, ref CuiElementContainer container) {
                if (!OpenUI.ContainsKey(player.userID)) OpenUI.Add(player.userID, new List<string>());
                foreach (var piece in container) OpenUI[player.userID].Add(piece.Name);
            }
            public static void DestroyUI(BasePlayer player) {
                CuiHelper.DestroyUi(player, Buttons);
                CuiHelper.DestroyUi(player, Main);
                CuiHelper.DestroyUi(player, MainOverlay);
                CuiHelper.DestroyUi(player, Mini);
                CuiHelper.DestroyUi(player, MiniOverlay);
                CuiHelper.DestroyUi(player, Complex);
                CuiHelper.DestroyUi(player, ComplexOverlay);
                if (!OpenUI.ContainsKey(player.userID)) return;
                foreach (var piece in OpenUI[player.userID]) CuiHelper.DestroyUi(player, piece);
            }
            public static string Color(string hexColor, float alpha) {
                int red = int.Parse(hexColor.Substring(0, 2), NumberStyles.AllowHexSpecifier);
                int green = int.Parse(hexColor.Substring(2, 2), NumberStyles.AllowHexSpecifier);
                int blue = int.Parse(hexColor.Substring(4, 2), NumberStyles.AllowHexSpecifier);
                return $"{(double)red / 255} {(double)green / 255} {(double)blue / 255} {alpha}";
            }
        }
        void GenerateMaps(bool main, bool mini, bool complex) {
            if (!ImageLibrary.IsReady()) {
                timer.In(30, () => GenerateMaps(main, mini, complex));
                Puts("[Warning] Waiting for Image Library to finish processing images");
                return;
            }
            if (main) CreateStaticMain();
            SetMinimapSize();
            if (mini) CreateStaticMini();
            if (complex) CreateStaticComplex();
        }
        void SetMinimapSize() {
            float startx = 0f + configData.MapOptions.MinimapOptions.OffsetSide;
            float endx = startx + (0.13f * configData.MapOptions.MinimapOptions.HorizontalScale);
            float endy = 1f - configData.MapOptions.MinimapOptions.OffsetTop;
            float starty = endy - (0.2301f * configData.MapOptions.MinimapOptions.VerticalScale);
            if (!configData.MapOptions.MinimapOptions.OnLeftSide) {
                endx = 1 - configData.MapOptions.MinimapOptions.OffsetSide;
                startx = endx - (0.13f * configData.MapOptions.MinimapOptions.HorizontalScale);
            }
            LustyUI.MiniMin = $"{startx} {starty}";
            LustyUI.MiniMax = $"{endx} {endy}";
        }
        void CreateStaticMain() {
            Puts("[Warning] Generating the main map");
            string mapimage = string.Empty;
            if (ImageLibrary.HasImage("mapimage", 0)) mapimage = GetImage("mapimage");
            else if (ImageLibrary.HasImage("mapimage_high", 0)) mapimage = GetImage("mapimage_high");
            if (string.IsNullOrEmpty(mapimage)) {
                Puts("[Error] Unable to load the map image from file storage.This may be caused by slow processing of the images being uploaded to your server.Wait for 5 minutes and reload the plugin.\nIf this problem persists after multiple attempts then unload the plugin and delete your ImageData.json data file or run the 'resetmap' command");
                activated = false;
                return;
            }
            float iconsize = 0.01f;
            LustyUI.MainMin = "0.2271875 0.015";
            LustyUI.MainMax = "0.7728125 0.985";
            var mapContainer = LMUI.CreateElementContainer(LustyUI.Main, "0 0 0 1", LustyUI.MainMin, LustyUI.MainMax, true);
            LMUI.LoadImage(ref mapContainer, LustyUI.Main, mapimage, "0 0", "1 1");
            LMUI.CreatePanel(ref mapContainer, LustyUI.Main, LustyUI.Color("2b627a", 0.4f), "0 0.96", "1 1");
            LMUI.CreateLabel(ref mapContainer, LustyUI.Main, "", $"{Title}  v{Version}", 14, "0.01 0.96", "0.99 1");
            foreach(var marker in staticMarkers) {
                var image = GetImage(marker.icon);
                if (string.IsNullOrEmpty(image)) continue;
                LMUI.LoadImage(ref mapContainer, LustyUI.Main, image, $"{marker.x - iconsize} {marker.z - iconsize}", $"{marker.x + iconsize} {marker.z + iconsize}");
                if (MapSettings.names) LMUI.CreateLabel(ref mapContainer, LustyUI.Main, "", marker.name, 10, $"{marker.x - 0.1} {marker.z - iconsize - 0.03}", $"{marker.x + 0.1} {marker.z - iconsize}");
            }
            LustyUI.StaticMain = mapContainer;
            Puts("[Warning] Main map generated successfully!");
            if (!MapSettings.minimap) LustyUI.RenameComponents();
        }
        void CreateStaticMini() {
            Puts("[Warning] Generating the mini-map");
            var mapimage = GetImage("mapimage");
            if (string.IsNullOrEmpty(mapimage)) {
                Puts("[Error] Unable to load the map image from file storage.This may be caused by slow processing of the images being uploaded to your server.Wait for 5 minutes and reload the plugin.\nIf this problem persists after multiple attempts then unload the plugin and delete your ImageData.json data file or run the 'resetmap' command");
                activated = false;
                return;
            }
            float iconsize = 0.03f;
            var mapContainer = LMUI.CreateElementContainer(LustyUI.Mini, "0 0 0 1", LustyUI.MiniMin, LustyUI.MiniMax);
            LMUI.LoadImage(ref mapContainer, LustyUI.Mini, mapimage, "0 0", "1 1");
            foreach (var marker in staticMarkers) {
                var image = GetImage(marker.icon);
                if (string.IsNullOrEmpty(image)) continue;
                LMUI.LoadImage(ref mapContainer, LustyUI.Mini, image, $"{marker.x - iconsize} {marker.z - iconsize}", $"{marker.x + iconsize} {marker.z + iconsize}");
            }
            LustyUI.StaticMini = mapContainer;
            Puts("[Warning] Mini map generated successfully!");
            if (!MapSettings.complexmap) LustyUI.RenameComponents();
        }
        void CreateStaticComplex() {
            Puts("[Warning] Generating the complex map.This may take a few moments, please wait!");
            foreach (var mapslices in new List<int> {
                6, 12, 26
            }
            ) //, 32 })
            {
                for (int number = 0; number < (mapslices * mapslices);
                number++) {
                    int rowNum = 0;
                    int colNum = 0;
                    if (number > mapslices - 1) {
                        colNum = Convert.ToInt32(Math.Floor((float)number / (float)mapslices));
                        rowNum = number - (colNum * mapslices);
                    }
                    else rowNum = number;
                    var mapContainer = LMUI.CreateElementContainer(LustyUI.Complex, "0 0 0 1", LustyUI.MiniMin, LustyUI.MiniMax);
                    string imageId = GetImage($"map-{mapslices}-{rowNum}-{colNum}");
                    if (!string.IsNullOrEmpty(imageId)) LMUI.LoadImage(ref mapContainer, LustyUI.Complex, imageId, $"0 0", $"1 1");
                    else {
                        PrintError($"Missing map piece (Slices: {mapslices}, Column: {colNum}, Row: {rowNum}).When the plugin is splitting the map you must wait for it to finish otherwise the split will not complete and this error will occur");
                        PrintError($"Creating a new load order with ImageLibrary");
                        LoadImages();
                        LoadMapImage();
                        return;
                    }
                    double width = ((double)1 / (double)mapslices);
                    float iconsize = 0.03f;
                    var column = colNum;
                    var row = rowNum;
                    if (column < 1) column = 1;
                    if (column > mapslices - 2) column = mapslices - 2;
                    if (row < 1) row = 1;
                    if (row > mapslices - 2) row = mapslices - 2;
                    double colStart = (width * column) - width;
                    double colEnd = colStart + (width * 3);
                    double rowStart = 1 - ((width * row) - width);
                    double rowEnd = (rowStart - (width * 3));
                    foreach (var marker in staticMarkers) {
                        string markerId = GetImage(marker.icon);
                        if (string.IsNullOrEmpty(markerId)) continue;
                        float x = marker.x;
                        float z = marker.z;
                        if ((x > colStart && x < colEnd) && (z > rowEnd && z < rowStart)) {
                            var average = 1 / (colEnd - colStart);
                            double posX = (x - colStart) * average;
                            double posZ = (z - rowEnd) * average;
                            LMUI.LoadImage(ref mapContainer, LustyUI.Complex, markerId, $"{posX - iconsize} {posZ - iconsize}", $"{posX + iconsize} {posZ + iconsize}");
                        }
                    }
                    int zoom = CountToZoom(mapslices);
                    if (!LustyUI.StaticComplex.ContainsKey(zoom)) LustyUI.StaticComplex.Add(zoom, new CuiElementContainer[mapslices, mapslices]);
                    LustyUI.StaticComplex[zoom][colNum, rowNum] = mapContainer;
                }
            }
            Puts("[Warning] Complex map generated successfully!");
            LustyUI.RenameComponents();
        }
        static int ZoomToCount(int zoom) {
            switch (zoom) {
                case 1 : return 6;
                case 2 : return 12;
                case 3 : return 26;
                case 4 : return 32;
                default : return 0;
            }
        }
        static int CountToZoom(int count) {
            switch (count) {
                case 6 : return 1;
                case 12 : return 2;
                case 26 : return 3;
                case 32 : return 4;
                default : return 0;
            }
        }
#endregion
#region Maps
        void ActivateMaps() {
            foreach (var player in BasePlayer.activePlayerList) OnPlayerInit(player);
        }
        void AddMapCompass(BasePlayer player, ref CuiElementContainer mapContainer, string panel, int fontsize, string offsetMin, string offsetMax) {
            string direction = null;
            if (player?.eyes?.rotation == null) return;
            float lookRotation = player?.eyes?.rotation.eulerAngles.y ?? 0;
            int playerdirection = (Convert.ToInt16((lookRotation - 5) / 10 + 0.5) * 10);
            if (lookRotation >= 355) playerdirection = 0;
            if (lookRotation > 337.5 || lookRotation < 22.5) {
                direction = msg("cpsN");
            }
            else if (lookRotation > 22.5 && lookRotation < 67.5) {
                direction = msg("cpsNE");
            }
            else if (lookRotation > 67.5 && lookRotation < 112.5) {
                direction = msg("cpsE");
            }
            else if (lookRotation > 112.5 && lookRotation < 157.5) {
                direction = msg("cpsSE");
            }
            else if (lookRotation > 157.5 && lookRotation < 202.5) {
                direction = msg("cpsS");
            }
            else if (lookRotation > 202.5 && lookRotation < 247.5) {
                direction = msg("cpsSW");
            }
            else if (lookRotation > 247.5 && lookRotation < 292.5) {
                direction = msg("cpsW");
            }
            else if (lookRotation > 292.5 && lookRotation < 337.5) {
                direction = msg("cpsNW");
            }
            LMUI.CreateLabel(ref mapContainer, panel, "", $"<size={fontsize + 4}>{direction}</size> \n{player.transform.position}", fontsize, offsetMin, offsetMax, TextAnchor.UpperCenter);
        }
        void AddMapButtons(BasePlayer player) {
            float startx = 0f + configData.MapOptions.MinimapOptions.OffsetSide;
            float endx = startx + (0.13f * configData.MapOptions.MinimapOptions.HorizontalScale);
            float endy = 1f - configData.MapOptions.MinimapOptions.OffsetTop;
            float starty = endy - (0.2301f * configData.MapOptions.MinimapOptions.VerticalScale);
            string b_text = "<<<";
            var container = LMUI.CreateElementContainer(LustyUI.Buttons, "0 0 0 0", $"{endx + 0.001f} {starty}", $"{endx + 0.02f} {endy}");
            if (!configData.MapOptions.MinimapOptions.OnLeftSide) {
                endx = 1 - configData.MapOptions.MinimapOptions.OffsetSide;
                startx = endx - (0.13f * configData.MapOptions.MinimapOptions.HorizontalScale);
                b_text = ">>>";
                container = LMUI.CreateElementContainer(LustyUI.Buttons, "0 0 0 0", $"{startx - 0.02f} {starty}", $"{startx - 0.001f} {endy}");
            }
            LMUI.CreateButton(ref container, LustyUI.Buttons, LustyUI.Color("696969", 0.6f), b_text, 12, $"0 0.9", $"1 1", "LMUI_Control shrink");
            if (MapSettings.complexmap && !MapSettings.forcedzoom) {
                LMUI.CreateButton(ref container, LustyUI.Buttons, LustyUI.Color("696969", 0.6f), "+", 14, $"0 0.79", $"1 0.89", "LMUI_Control zoomin");
                LMUI.CreateButton(ref container, LustyUI.Buttons, LustyUI.Color("696969", 0.6f), "-", 14, $"0 0.68", $"1 0.78", "LMUI_Control zoomout");
            }
            CuiHelper.DestroyUi(player, LustyUI.Buttons);
            CuiHelper.AddUi(player, container);
        }
        void CreateShrunkUI(BasePlayer player) {
            var user = GetUser(player);
            if (user == null) return;
            float b_endy = 0.999f - configData.MapOptions.MinimapOptions.OffsetTop;
            float b_startx = 0.001f + configData.MapOptions.MinimapOptions.OffsetSide;
            float b_endx = b_startx + 0.02f;
            string b_text = ">>>";
            if (!configData.MapOptions.MinimapOptions.OnLeftSide) {
                b_endx = 0.999f - configData.MapOptions.MinimapOptions.OffsetSide;
                b_startx = b_endx - 0.02f;
                b_text = "<<<";
            }
            var container = LMUI.CreateElementContainer(LustyUI.Buttons, "0 0 0 0", $"{b_startx} {b_endy - 0.025f}", $"{b_endx} {b_endy}");
            LMUI.CreateButton(ref container, LustyUI.Buttons, LustyUI.Color("696969", 0.6f), b_text, 12, "0 0", "1 1", "LMUI_Control expand");
            CuiHelper.DestroyUi(player, LustyUI.Buttons);
            CuiHelper.AddUi(player, container);
        }
#region Standard Maps
        void OpenMainMap(BasePlayer player) => LustyUI.AddBaseUI(player, MapMode.Main);
        void OpenMiniMap(BasePlayer player) => LustyUI.AddBaseUI(player, MapMode.Minimap);
        void UpdateOverlay(BasePlayer player, string panel, string posMin, string posMax, float iconsize) {
            var mapContainer = LMUI.CreateElementContainer(panel, "0 0 0 0", posMin, posMax);
            var user = GetUser(player);
            if (user == null) return;
            foreach (var marker in customMarkers) {
                var image = GetImage(marker.Key);
                if (string.IsNullOrEmpty(image)) continue;
                AddIconToMap(ref mapContainer, panel, image, marker.Value.name, iconsize * 1.25f, marker.Value.x, marker.Value.z);
            }
            foreach (var marker in temporaryMarkers) {
                var image = GetImage(marker.Key);
                if (string.IsNullOrEmpty(image)) continue;
                AddIconToMap(ref mapContainer, panel, image, marker.Value.name, iconsize * 1.25f, marker.Value.x, marker.Value.z);
            }
            foreach (var entity in entityMarkers) {
                var marker = entity.Value.GetMarker();
                if (marker == null) continue;
                var image = GetImage(marker.icon);
                if (string.IsNullOrEmpty(image)) continue;
                AddIconToMap(ref mapContainer, panel, image, "", entity.Value.type == AEType.Vending ? iconsize : iconsize * 1.4f, marker.x, marker.z);
            }
            if (user.IsAdmin || MapSettings.allplayers) {
                foreach (var mapuser in mapUsers) {
                    if (mapuser.Key == player.UserIDString) continue;
                    var marker = mapuser.Value.GetMarker();
                    if (marker == null) continue;
                    var image = GetImage($"other{marker.r}");
                    if (string.IsNullOrEmpty(image)) continue;
                    AddIconToMap(ref mapContainer, panel, image, marker.name, iconsize * 1.25f, marker.x, marker.z);
                }
            }
            else if (MapSettings.friends) {
                foreach (var friendId in user.friendList) {
                    if (friendId == player.UserIDString) continue;
                    if (mapUsers.ContainsKey(friendId)) {
                        var friend = mapUsers[friendId];
                        if (friend.InEvent() && configData.MapOptions.HideEventPlayers) continue;
                        var marker = friend.GetMarker();
                        if (marker == null) continue;
                        var image = GetImage($"friend{marker.r}");
                        if (string.IsNullOrEmpty(image)) continue;
                        AddIconToMap(ref mapContainer, panel, image, marker.name, iconsize * 1.25f, marker.x, marker.z);
                    }
                }
            }
            if (MapSettings.player) {
                var selfMarker = user.GetMarker();
                if (selfMarker != null) {
                    var selfImage = GetImage($"self{selfMarker.r}");
                    AddIconToMap(ref mapContainer, panel, selfImage, "", iconsize * 1.25f, selfMarker.x, selfMarker.z);
                }
            }
            if (panel == LustyUI.MainOverlay) {
                LMUI.CreateButton(ref mapContainer, panel, LustyUI.Color("88a8b6", 1), "X", 14, "0.95 0.961", "0.999 0.999", "LMUI_Control map");
                if (MapSettings.compass) AddMapCompass(player, ref mapContainer, panel, 14, "0.75 0.88", "1 0.95");
            }
            if (panel == LustyUI.MiniOverlay) {
                if (MapSettings.compass) AddMapCompass(player, ref mapContainer, panel, 10, "0 -0.25", "1 -0.02");
            }
            CuiHelper.DestroyUi(player, panel);
            CuiHelper.AddUi(player, mapContainer);
        }
        void AddIconToMap(ref CuiElementContainer mapContainer, string panel, string image, string name, float iconsize, float posX, float posZ) {
            if (posX < iconsize || posX > 1 - iconsize || posZ < iconsize || posZ > 1 - iconsize) return;
            LMUI.LoadImage(ref mapContainer, panel, image, $"{posX - iconsize} {posZ - iconsize}", $"{posX + iconsize} {posZ + iconsize}");
            if (MapSettings.names) LMUI.CreateLabel(ref mapContainer, panel, "", name, 10, $"{posX - 0.1} {posZ - iconsize - 0.025}", $"{posX + 0.1} {posZ - iconsize}");
        }
#endregion
#region Complex Maps
        void
// ... [Code preview truncated due to length. Full source in attached file] ...

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