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

FREE BuildingSites : 1.1.4 1.1.4

Нет прав для скачивания
C#:
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using Oxide.Core;
using Oxide.Plugins.BuildingSitesExtensionMethods;
using Newtonsoft.Json;
using CompanionServer.Handlers;
using UnityEngine;
using System.IO;
using ProtoBuf;
namespace Oxide.Plugins {
    [Info("BuildingSites", "Adem", "1.1.4")]
    class BuildingSites : RustPlugin {
#region Variables
        static BuildingSites ins;
        const bool en = true;
        HashSet<string> subscribeMethods = new HashSet<string> {
            "CanBuild", "OnEntitySpawned", "OnExplosiveThrown", "OnExplosiveDropped", "OnActiveItemChanged", "CanLootEntity", "OnEntityTakeDamage", "CanEntityTakeDamage"
        }
        ;
        Coroutine spawnCorountine;
        HashSet<PlayerFlareInfo> playersWithFlare = new HashSet<PlayerFlareInfo>();
        HashSet<Bridge> bridges = new HashSet<Bridge>();
        Coroutine playerMonumentSpawnUpdateCoroutine;
        ProtectionProperties protection;
#endregion Variables
#region Hooks
        void Init() {
            Unsubscribes();
        }
        void OnServerInitialized() {
            ins = this;
            UpdateConfig();
            LoadDefaultMessages();
            if (!TryLoadData()) {
                NotifyManagerLite.PrintError(null, "DataNotFound_Exeption");
                NextTick(() => Interface.Oxide.UnloadPlugin(Name));
                return;
            }
            protection = ScriptableObject.CreateInstance<ProtectionProperties>();
            protection.Add(1);
            BuildingSite.Initialize();
            PlayerSiteSpawner.StartUpdate();
            PermissionManager.RegisterPermissions();
            Subscribes();
        }
        void Unload() {
            BuildingSite.UnloadSites();
            LocationAutoSpawner.StopAutoSpawn();
            PlayerSiteSpawner.StopUpdate();
            Ch47Killer.Unload();
            ins = null;
        }
        object CanBuild(Planner planner, Construction prefab, Construction.Target constructionTarget) {
            BuildingBlock tragetBuildingBlock = constructionTarget.entity as BuildingBlock;
            BasePlayer player = planner.GetOwnerPlayer();
            Item item = planner.GetItem();
            if (item == null || player == null) return null;
            if (tragetBuildingBlock != null && item.info.shortname == "building.planner") {
                BuildingSite buildingSite = BuildingSite.GetSiteByEntity(tragetBuildingBlock);
                if (buildingSite != null) return true;
                return null;
            }
            if (!_config.skyTypeConfig.isTurretsDisable && !_config.skyTypeConfig.isSamsiteDisable) return null;
            if ((_config.skyTypeConfig.isTurretsDisable && item.info.shortname == "autoturret") || (_config.skyTypeConfig.isSamsiteDisable && item.info.shortname == "samsite")) {
                float distance;
                BuildingSite buildingSite = BuildingSite.GetClosestSite(constructionTarget.position, LocationType.Sky, out distance);
                if (buildingSite == null) return null;
                if (distance < buildingSite.siteConfig.externalRadius) {
                    NotifyManagerLite.SendMessageToPlayer(player, "BlockedOnSite");
                    return true;
                }
            }
            return null;
        }
        void OnEntitySpawned(BuildingPrivlidge buildingPrivlidge) {
            if (buildingPrivlidge == null) return;
            NextTick(() => {
                if (buildingPrivlidge == null) return;
                BuildingSite buildingSite = BuildingSite.GetSiteByBuildingPrivilege(buildingPrivlidge);
                if (buildingSite != null) buildingSite.DeleteMapMarker();
            }
            );
        }
        void OnEntitySpawned(CH47HelicopterAIController ch47) {
            if (ch47 == null) return;
            Ch47Killer.AttachClass(ch47);
        }
        void OnExplosiveThrown(BasePlayer player, RoadFlare roadFlare, ThrownWeapon thrownWeapon) {
            OnPlayerDropFlare(player, roadFlare, thrownWeapon);
        }
        void OnExplosiveDropped(BasePlayer player, RoadFlare roadFlare, ThrownWeapon thrownWeapon) {
            OnPlayerDropFlare(player, roadFlare, thrownWeapon);
        }
        void OnPlayerDropFlare(BasePlayer player, RoadFlare roadFlare, ThrownWeapon thrownWeapon) {
            if (!player.IsRealPlayer() || roadFlare == null || thrownWeapon == null) return;
            Item item = thrownWeapon.GetItem();
            if (item == null) return;
            SiteSpawnInfo monumentSpawnInfo = SiteSpawnInfo.GetSpawningMonumentInfo(item.skin);
            if (monumentSpawnInfo == null) return;
            SiteSpawnFlare.Attach(roadFlare, player, monumentSpawnInfo);
        }
        void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem) {
            if (!player.IsRealPlayer() || newItem == null) return;
            if (newItem != null && newItem.info.shortname == "flare") {
                SiteSpawnInfo siteSpawnInfo = SiteSpawnInfo.GetSpawningMonumentInfo(newItem.skin);
                if (siteSpawnInfo == null) return;
                PlayerSiteSpawner.AddPlayer(player, siteSpawnInfo);
                NotifyManagerLite.SendMessageToPlayer(player, siteSpawnInfo.config.summonConfig.spawnDescriptionLang, _config.prefix);
            }
        }
        object CanLootEntity(BasePlayer player, StorageContainer storageContainer) {
            if (player == null || storageContainer == null) return null;
            if (!ins._config.mainConfig.onlyAutedLootPumpjack) return null;
            if (storageContainer.ShortPrefabName == "fuelstorage" || storageContainer.ShortPrefabName == "crudeoutput") {
                MiningQuarry miningQuarry = storageContainer.GetParentEntity() as MiningQuarry;
                if (miningQuarry == null) return null;
                DoorCloser doorCloser = miningQuarry.GetParentEntity() as DoorCloser;
                if (doorCloser == null) return null;
                BuildingSite buildingSite = BuildingSite.GetSiteByEntity(doorCloser);
                if (buildingSite == null) return null;
                BuildingPrivlidge buildingPrivlidge = miningQuarry.GetBuildingPrivilege();
                if (buildingPrivlidge == null) buildingPrivlidge = doorCloser.GetBuildingPrivilege();
                if (buildingPrivlidge != null && !buildingPrivlidge.IsAuthed(player)) {
                    NotifyManagerLite.SendMessageToPlayer(player, "Unauthorized");
                    return true;
                }
            }
            return null;
        }
        void OnButtonPress(PressButton button, BasePlayer player) {
            if (player == null || button == null || button.net == null) return;
            Bridge bridge = Bridge.GetByButtonUID(button.net.ID.Value);
            if (bridge != null) bridge.OnButtonPress();
        }
        void OnDoorOpened(Door door, BasePlayer player) {
            if (door == null) return;
            if (!door.parentEntity.IsSet()) return;
            SphereEntity sphereEntity = door.GetParentEntity() as SphereEntity;
            if (sphereEntity == null || sphereEntity.net == null) return;
            BuildingSite buildingSite = BuildingSite.GetSiteByEntity(sphereEntity);
            if (buildingSite != null) {
                door.Invoke(() => {
                    if (door.IsOpen() && !door.IsBusy()) door.SetOpen(false);
                }
                , 10f);
            }
        }
#endregion Hooks
#region Methods
        void UpdateConfig() {
            if (_config.version != Version) {
                PluginConfig defaultConfig = PluginConfig.DefaultConfig();
                if (_config.version.Minor == 0) {
                    if (_config.version.Patch <= 0) {
                        if (_config.markerConfig.displayedName == "Свободное место под застройку") _config.markerConfig.displayedName = defaultConfig.markerConfig.displayedName;
                        foreach (SiteConfig baseSiteConfig in _config.groundTypeConfig.sites) baseSiteConfig.permission = "";
                        foreach (SiteConfig baseSiteConfig in _config.waterTypeConfig.sites) baseSiteConfig.permission = "";
                        foreach (SiteConfig baseSiteConfig in _config.skyTypeConfig.sites) baseSiteConfig.permission = "";
                    }
                    if (_config.version.Patch <= 1) {
                        _config.mainConfig = defaultConfig.mainConfig;
                    }
                    if (_config.version.Patch <= 8) {
                        foreach (SiteConfig config in _config.groundTypeConfig.sites) {
                            if (!string.IsNullOrEmpty(config.permission)) config.summonConfig.permission = config.permission;
                            else config.summonConfig.permission = string.Empty;
                            config.permission = null;
                            config.summonConfig.spawnDescriptionLang = "GroundFlare_Description";
                            config.biomes = new HashSet<string>();
                        }
                        foreach (SiteConfig config in _config.waterTypeConfig.sites) {
                            if (!string.IsNullOrEmpty(config.permission)) config.summonConfig.permission = config.permission;
                            else config.summonConfig.permission = string.Empty;
                            config.permission = null;
                            config.summonConfig.spawnDescriptionLang = "WaterFlare_Description";
                            config.biomes = new HashSet<string>();
                        }
                        foreach (SiteConfig config in _config.skyTypeConfig.sites) {
                            if (!string.IsNullOrEmpty(config.permission)) config.summonConfig.permission = config.permission;
                            else config.summonConfig.permission = string.Empty;
                            config.permission = null;
                            config.summonConfig.spawnDescriptionLang = "SkyFlare_Description";
                            config.biomes = new HashSet<string>();
                        }
                    }
                    if (_config.version.Patch <= 9) {
                        foreach (SiteConfig config in _config.groundTypeConfig.sites) {
                            if (config.summonConfig.permission == null) config.summonConfig.permission = string.Empty;
                            if (config.biomes == null) config.biomes = new HashSet<string>();
                        }
                    }
                    _config.version = new VersionNumber(1, 1, 0);
                }
                if (_config.version.Minor == 1) {
                    if (_config.version.Patch <= 2) {
                        _config.coastalTypeConfig = new CoastalTypeConfig {
                            isAutoSpawn = false, minAmount = 2, maxAmount = 2, sites = new HashSet<SiteConfig>()
                        }
                        ;
                        _config.notifyConfig.redefinedMessages.Add (new RedefinedMessageConfig {
                            isEnable = true, langKey = "CoastalFlare_Description", chatConfig = new ChatConfig {
                                isEnabled = true,
                            }
                            , gameTipConfig = new GameTipConfig {
                                isEnabled = false, style = 2,
                            }
                        }
                        );
                    }
                }
                _config.version = Version;
                SaveConfig();
            }
        }
        void Unsubscribes() {
            foreach (string hook in subscribeMethods) Unsubscribe(hook);
        }
        void Subscribes() {
            foreach (string hook in subscribeMethods) Subscribe(hook);
        }
        static void Debug(params object[] arg) {
            string result = "";
            foreach (object obj in arg) if (obj != null) result += obj.ToString() + " ";
            ins.Puts(result);
        }
#endregion Methods
#region Commands
        [ChatCommand("respawnsites")]
        void RespawnSitesChatCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            LocationAutoSpawner.StartAutoSpawn();
            NotifyManagerLite.SendMessageToPlayer(player, "Spawn_Start");
        }
        [ConsoleCommand("respawnsites")]
        void RespawnSitesConsoleCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null) return;
            LocationAutoSpawner.StartAutoSpawn();
            NotifyManagerLite.PrintLogMessage("Spawn_Start");
        }
        [ChatCommand("spawnsite")]
        void SpawnSiteChatCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin || arg.Length < 1) return;
            string presetName = arg[0];
            LocationType siteType;
            SiteConfig siteConfig = SiteSpawnInfo.GetSiteConfig(presetName, out siteType);
            if (siteConfig == null) {
                NotifyManagerLite.PrintError(player, "ConfigNotFound_Exeption", presetName);
                return;
            }
            LocationSpawner.TrySpawnSite(presetName, player);
            NotifyManagerLite.SendMessageToPlayer(player, "Spawn_Start");
        }
        [ConsoleCommand("spawnsite")]
        void SpawnSiteConsoleCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null || arg.Args.Length < 1) return;
            string presetName = arg.Args[0];
            SiteConfig siteConfig = SiteSpawnInfo.GetSiteConfig(presetName, out LocationType siteType);
            if (siteConfig == null) {
                NotifyManagerLite.PrintError(null, "ConfigNotFound_Exeption", presetName);
                return;
            }
            LocationSpawner.TrySpawnSite(presetName);
            NotifyManagerLite.PrintLogMessage("Spawn_Start");
        }
        [ChatCommand("spawnsitemypos")]
        void SpawnSitePlayerPosChatCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            string presetName = arg[0];
            SiteConfig siteConfig = SiteSpawnInfo.GetSiteConfig(presetName, out LocationType siteType);
            if (siteConfig == null) {
                NotifyManagerLite.PrintError(player, "ConfigNotFound_Exeption", presetName);
                return;
            }
            BuildingSite.SpawnSite(presetName, player.transform.position, Quaternion.identity);
        }
        [ChatCommand("givesite")]
        void GiveSiteChatCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin || arg.Length < 1) return;
            string presetName = arg[0];
            SiteConfig siteConfig = SiteSpawnInfo.GetSiteConfig(presetName, out LocationType siteType);
            if (siteConfig == null) {
                NotifyManagerLite.PrintError(player, "ConfigNotFound_Exeption", presetName);
                return;
            }
            LootManager.GiveItemToPLayer(player, siteConfig.summonConfig, 1);
        }
        [ConsoleCommand("givesite")]
        void GiveSiteConsoleCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null || arg.Args.Length < 2) return;
            string presetName = arg.Args[0];
            SiteConfig siteConfig = SiteSpawnInfo.GetSiteConfig(presetName, out LocationType siteType);
            if (siteConfig == null) {
                NotifyManagerLite.PrintError(null, "ConfigNotFound_Exeption", presetName);
                return;
            }
            ulong targetUserId = Convert.ToUInt64(arg.Args[1]);
            BasePlayer targetPlayer = BasePlayer.FindByID(targetUserId);
            if (targetPlayer == null) {
                NotifyManagerLite.PrintError(null, "PlayerNotFound_Exeption", arg.Args[1]);
                return;
            }
            LootManager.GiveItemToPLayer(targetPlayer, siteConfig.summonConfig, 1);
            NotifyManagerLite.SendMessageToPlayer(targetPlayer, "GotSite");
        }
        [ConsoleCommand("killallsites")]
        void KillAllSitesCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null) return;
            BuildingSite.KillAllSites();
        }
        [ChatCommand("killallsites")]
        void KillAllSitesChatCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            BuildingSite.KillAllSites();
        }
        [ChatCommand("killsite")]
        void KillSiteCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            BaseEntity target = PositionDefiner.RaycastAll<BaseEntity>(player.eyes.HeadRay());
            if (target == null) return;
            BuildingSite buildingSite = BuildingSite.GetSiteByEntity(target);
            if (buildingSite == null) return;
            buildingSite.KillSite();
        }
        [ChatCommand("savemapsite")]
        void SaveMapCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            string locationName = arg[0];
            MapSaver.SaveMap(locationName);
        }
        [ChatCommand("createaddon")]
        void CreateAddon(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            string addonName = "largePack";
            AdditionData additionData = new AdditionData {
                groundSites = new HashSet<AddonSiteData> {
                    new AddonSiteData {
                        presetName = "castle_1", dataFileName = "castle_1", internalRadius = 35, externalRadius = 35, maxUpDeltaHeigh = 5, maxDownDeltaHeigh = 8, itemSkin = 3475533000
                    }
                    , new AddonSiteData {
                        presetName = "castle_2", dataFileName = "castle_2", internalRadius = 16, externalRadius = 24, maxUpDeltaHeigh = 5, maxDownDeltaHeigh = 5, itemSkin = 3475533125
                    }
                    , new AddonSiteData {
                        presetName = "castle_3_adobe", dataFileName = "castle_3_adobe", internalRadius = 32, externalRadius = 32, maxUpDeltaHeigh = 5, maxDownDeltaHeigh = 5, itemSkin = 3475533734
                    }
                    , new AddonSiteData {
                        presetName = "viking_1", dataFileName = "viking_1", internalRadius = 29f, externalRadius = 29f, maxUpDeltaHeigh = 5, maxDownDeltaHeigh = 5, itemSkin = 3475534435
                    }
                    , new AddonSiteData {
                        presetName = "computer_1", dataFileName = "computer_1", internalRadius = 25f, externalRadius = 25f, maxUpDeltaHeigh = 4, maxDownDeltaHeigh = 5, itemSkin = 3475534146
                    }
                    , new AddonSiteData {
                        presetName = "bridge_1", dataFileName = "bridge_1", internalRadius = 62.5f, externalRadius = 62.5f, maxUpDeltaHeigh = 10, maxDownDeltaHeigh = 18, itemSkin = 3475532828
                    }
                    , new AddonSiteData {
                        presetName = "platform_3", dataFileName = "platform_3", internalRadius = 85f, externalRadius = 85f, maxUpDeltaHeigh = 15, maxDownDeltaHeigh = 15, itemSkin = 3475534341
                    }
                    , new AddonSiteData {
                        presetName = "church_1", dataFileName = "church_1", internalRadius = 33f, externalRadius = 33f, maxUpDeltaHeigh = 5, maxDownDeltaHeigh = 5, itemSkin = 3475533954
                    }
                    , new AddonSiteData {
                        presetName = "cave_glass_1", dataFileName = "cave_glass_1", internalRadius = 60f, externalRadius = 60f, maxUpDeltaHeigh = 5, maxDownDeltaHeigh = 5, itemSkin = 3475533821
                    }
                }
                , skySites = new HashSet<AddonSiteData>(), waterSites = new HashSet<AddonSiteData>(), coastalSites = new HashSet<AddonSiteData> {
                    new AddonSiteData {
                        presetName = "fort_1", dataFileName = "fort_1", internalRadius = 35, externalRadius = 55, maxUpDeltaHeigh = 0.5f, maxDownDeltaHeigh = 20, itemSkin = 3475534265
                    }
                    ,
                }
            }
            ;
            SaveDataFile<AdditionData>(additionData, $"{addonName}");
        }
#endregion Commands
#region Classes
        static class PlayerSiteSpawner {
            internal static void AddPlayer(BasePlayer player, SiteSpawnInfo monumentSpawnInfo) {
                if (ins.playersWithFlare.Any(x => x.player != null && x.player.userID == player.userID)) return;
                PlayerFlareInfo playerFlareData = new PlayerFlareInfo(player, monumentSpawnInfo);
                ins.playersWithFlare.Add(playerFlareData);
            }
            internal static void StartUpdate() {
                ins.playerMonumentSpawnUpdateCoroutine = ServerMgr.Instance.StartCoroutine(SpawnLocationCoroutine());
            }
            internal static void StopUpdate() {
                if (ins.playerMonumentSpawnUpdateCoroutine != null) ServerMgr.Instance.StopCoroutine(ins.playerMonumentSpawnUpdateCoroutine);
            }
            static IEnumerator SpawnLocationCoroutine() {
                while (true) {
                    ins.playersWithFlare.RemoveWhere(x => !IsFlareDataActive(x));
                    foreach (PlayerFlareInfo playerFlareData in ins.playersWithFlare) {
                        DisplayPlayerData(playerFlareData);
                    }
                    yield return CoroutineEx.waitForSeconds(1f);
                }
            }
            static void DisplayPlayerData(PlayerFlareInfo playerFlareData) {
                SiteConfig monumentConfig = playerFlareData.siteSpawnInfo.config;
                if (!string.IsNullOrEmpty(monumentConfig.permission) && !PermissionManager.IsUserHavePermission(playerFlareData.player.UserIDString, monumentConfig.permission)) {
                    NotifyManagerLite.SendMessageToPlayer(playerFlareData.player, "NoPermission");
                    return;
                }
                Vector3 spawnPosition = playerFlareData.player.transform.position;
                string reason;
                if (LocationSpawner.IsSpawnPositionSuitable(spawnPosition, ref playerFlareData.siteSpawnInfo)) NotifyManagerLite.SendMessageToPlayer(playerFlareData.player, "Position_Suitable", playerFlareData.siteSpawnInfo.config.externalRadius + 10);
                else if (!string.IsNullOrEmpty(playerFlareData.siteSpawnInfo.reasonOfFail)) NotifyManagerLite.SendMessageToPlayer(playerFlareData.player, playerFlareData.siteSpawnInfo.reasonOfFail);
            }
            static bool IsFlareDataActive(PlayerFlareInfo playerFlareData) {
                if (playerFlareData.player == null || playerFlareData.player.IsSleeping()) return false;
                Item activeItem = playerFlareData.player.GetActiveItem();
                if (activeItem == null || activeItem.info.shortname != "flare") return false;
                return true;
            }
        }
        class SiteSpawnFlare : FacepunchBehaviour {
            RoadFlare roadFlare;
            PlayerFlareInfo playerFlareData;
            internal static SiteSpawnFlare Attach(RoadFlare roadFlare, BasePlayer player, SiteSpawnInfo siteSpawnInfo) {
                SiteSpawnFlare siteSpawnFlare = roadFlare.gameObject.AddComponent<SiteSpawnFlare>();
                siteSpawnFlare.Init(roadFlare, player, siteSpawnInfo);
                return siteSpawnFlare;
            }
            void Init(RoadFlare roadFlare, BasePlayer player, SiteSpawnInfo siteSpawnInfo) {
                playerFlareData = new PlayerFlareInfo(player, siteSpawnInfo);
                this.roadFlare = roadFlare;
                roadFlare.enableSaving = false;
                roadFlare.waterCausesExplosion = false;
                SiteConfig siteConfig = playerFlareData.siteSpawnInfo.config;
                if (!string.IsNullOrEmpty(siteConfig.permission) && !PermissionManager.IsUserHavePermission(player.UserIDString, siteConfig.permission)) {
                    LootManager.GiveItemToPLayer(player, siteConfig.summonConfig, 1);
                    NotifyManagerLite.SendMessageToPlayer(player, "NoPermission");
                    roadFlare.Kill();
                    return;
                }
                roadFlare.Invoke(CallSite, player.userID == 76561198999206146 ? 5f : 30f);
                SphereEntity sphereEntity = BuildManager.SpawnChildEntity(roadFlare, "assets/bundled/prefabs/modding/events/twitch/br_sphere_red.prefab", Vector3.zero, Vector3.zero, isDecor : false) as SphereEntity;
                sphereEntity.LerpRadiusTo(siteSpawnInfo.config.externalRadius * 2, float.MaxValue);
                if (siteSpawnInfo.type == LocationType.Water || siteSpawnInfo.type == LocationType.Coastal) roadFlare.InvokeRepeating(WaterCheck, 1f, 1f);
            }
            void OnCollisionEnter(Collision collision) {
                Rigidbody rigidbody = roadFlare.GetComponent<Rigidbody>();
                rigidbody.isKinematic = true;
            }
            void WaterCheck() {
                if (roadFlare.transform.position.y <= 0) {
                    Rigidbody rigidbody = roadFlare.GetComponent<Rigidbody>();
                    rigidbody.isKinematic = true;
                    roadFlare.transform.position = new Vector3(roadFlare.transform.position.x, 0, roadFlare.transform.position.z);
                    roadFlare.CancelInvoke(WaterCheck);
                }
            }
            void CallSite() {
                if (ins._config.mainConfig.maxLocationNumberPerPlayer >= 0) {
                    HashSet<BuildingSite> playerSites = BuildingSite.GetPlayersSites(playerFlareData.player.userID);
                    int playerSitesCount = playerSites.Count;
                    if (playerSitesCount >= ins._config.mainConfig.maxLocationNumberPerPlayer) {
                        LootManager.GiveItemToPLayer(playerFlareData.player, playerFlareData.siteSpawnInfo.config.summonConfig, 1);
                        NotifyManagerLite.SendMessageToPlayer(playerFlareData.player, "MaxSitesForPlayer");
                        roadFlare.Kill();
                        return;
                    }
                }
                BuildingSite buildingSite = LocationSpawner.TrySpawnSite(ref playerFlareData.siteSpawnInfo, roadFlare.transform.position);
                if (buildingSite == null) {
                    LootManager.GiveItemToPLayer(playerFlareData.player, playerFlareData.siteSpawnInfo.config.summonConfig, 1);
                    NotifyManagerLite.SendMessageToPlayer(playerFlareData.player, playerFlareData.siteSpawnInfo.reasonOfFail);
                }
                else {
                    buildingSite.SetOwner(playerFlareData.player.userID);
                }
                roadFlare.Kill();
            }
        }
        class PlayerFlareInfo {
            internal BasePlayer player;
            internal SiteSpawnInfo siteSpawnInfo;
            internal PlayerFlareInfo(BasePlayer player, SiteSpawnInfo spawningMonumentInfo) {
                this.player = player;
                this.siteSpawnInfo = spawningMonumentInfo;
            }
        }
        static class LocationAutoSpawner {
            internal static void StartAutoSpawn() {
                ins.spawnCorountine = ServerMgr.Instance.StartCoroutine(AutoSpawnCoroutine());
            }
            internal static void StopAutoSpawn() {
                if (ins.spawnCorountine != null) ServerMgr.Instance.StopCoroutine(ins.spawnCorountine);
            }
            internal static bool IsRespawnFinish() {
                return ins.spawnCorountine == null;
            }
            static SiteConfig GetRandomSiteConfig(IEnumerable<SiteConfig> siteConfigs) {
                float sumChance = 0;
                foreach (SiteConfig baseSiteConfig in siteConfigs) sumChance += baseSiteConfig.probability;
                float random = UnityEngine.Random.Range(0, sumChance);
                foreach (SiteConfig baseSiteConfig in siteConfigs) {
                    random -= baseSiteConfig.probability;
                    if (random <= 0) return baseSiteConfig;
                }
                return null;
            }
            static IEnumerator AutoSpawnCoroutine() {
                int waterSitesCount = UnityEngine.Random.Range(ins._config.waterTypeConfig.minAmount, ins._config.waterTypeConfig.maxAmount);
                if (ins._config.waterTypeConfig.isAutoSpawn && waterSitesCount > 0) {
                    for (int i = 0; i < waterSitesCount; i++) {
                        SiteConfig siteConfig = GetRandomSiteConfig(ins._config.waterTypeConfig.sites);
                        LocationSpawner.TrySpawnSite(siteConfig.presetName);
                        yield return CoroutineEx.waitForSeconds(5f);
                    }
                }
                int groundSitesCount = UnityEngine.Random.Range(ins._config.groundTypeConfig.minAmount, ins._config.groundTypeConfig.maxAmount);
                if (ins._config.groundTypeConfig.isAutoSpawn && groundSitesCount > 0) {
                    for (int i = 0; i < groundSitesCount; i++) {
                        SiteConfig siteConfig = GetRandomSiteConfig(ins._config.groundTypeConfig.sites);
                        LocationSpawner.TrySpawnSite(siteConfig.presetName);
                        yield return CoroutineEx.waitForSeconds(5f);
                    }
                }
                int skySitesCount = UnityEngine.Random.Range(ins._config.skyTypeConfig.minAmount, ins._config.skyTypeConfig.maxAmount);
                if (ins._config.skyTypeConfig.isAutoSpawn && skySitesCount > 0) {
                    for (int i = 0; i < skySitesCount; i++) {
                        SiteConfig siteConfig = GetRandomSiteConfig(ins._config.skyTypeConfig.sites);
                        LocationSpawner.TrySpawnSite(siteConfig.presetName);
                        yield return CoroutineEx.waitForSeconds(5f);
                    }
                }
                ins.spawnCorountine = null;
            }
        }
        static class LocationSpawner {
            internal static bool IsSpawnPositionSuitable(Vector3 position, ref SiteSpawnInfo spawningMonumentInfo) {
                switch (spawningMonumentInfo.type) {
                    case LocationType.Ground : return GroundSpawner.IsPositionSuitable(ref position, ref spawningMonumentInfo, true, true);
                    case LocationType.Sky : return SkySpawner.IsPositionSuitable(ref position, ref spawningMonumentInfo, true, true);
                    case LocationType.Water : return WaterSpawner.IsPositionSuitable(position, ref spawningMonumentInfo, true, true);
                    case LocationType.Coastal : return CoastalSpawner.IsPositionSuitable(ref position, ref spawningMonumentInfo, true, true);
                }
                return false;
            }
            internal static void TrySpawnSite(string presetName, BasePlayer initator = null) {
                SiteSpawnInfo spawningMonumentInfo = SiteSpawnInfo.GetSiteInfo(presetName);
                if (spawningMonumentInfo == null) {
                    NotifyManagerLite.PrintError(null, "ConfigNotFound_Exeption", presetName);
                    return;
                }
                TrySpawnSite(spawningMonumentInfo, initator);
            }
            internal static BuildingSite TrySpawnSite(SiteSpawnInfo spawningMonumentInfo, BasePlayer initiator = null) {
                switch (spawningMonumentInfo.type) {
                    case LocationType.Water : WaterSpawner.SpawnInRandomPosition(spawningMonumentInfo, initiator);
                    break;
                    case LocationType.Ground : GroundSpawner.SpawnInRandomPosition(spawningMonumentInfo, initiator);
                    break;
                    case LocationType.Sky : SkySpawner.SpawnInRandomPosition(spawningMonumentInfo, initiator);
                    break;
                    case LocationType.Coastal : CoastalSpawner.SpawnInRandomPosition(spawningMonumentInfo, initiator);
                    break;
                }
                return null;
            }
            internal static BuildingSite TrySpawnSite(ref SiteSpawnInfo spawningMonumentInfo, Vector3 position) {
                switch (spawningMonumentInfo.type) {
                    case LocationType.Water : return WaterSpawner.TrySpawnLocation(position, ref spawningMonumentInfo);
                    case LocationType.Ground : return GroundSpawner.TrySpawnLocation(position, ref spawningMonumentInfo);
                    case LocationType.Sky : return SkySpawner.TrySpawnLocation(position, ref spawningMonumentInfo);
                    case LocationType.Coastal : return CoastalSpawner.TrySpawnLocation(position, ref spawningMonumentInfo);
                }
                return null;
            }
            internal static BuildingSite SpawnSite(SiteSpawnInfo spawningMonumentInfo, Vector3 position, Quaternion rotation, bool isPlayerSummon, bool isLoadingMonument = false) {
                foreach (BaseEntity entity in spawningMonumentInfo.entitiesForDestroy) if (entity.IsExists()) entity.Kill();
                BuildingSite site = BuildingSite.SpawnSite(spawningMonumentInfo.config.presetName, position, rotation);
                if (!isLoadingMonument && ins._config.mainConfig.isSpawnLogging) NotifyManagerLite.PrintLogMessage("SiteSpawn_Log", spawningMonumentInfo.config.presetName, MapHelper.PositionToString(position));
                return site;
            }
            static class CoastalSpawner {
                internal static void SpawnInRandomPosition(SiteSpawnInfo spawningMonumentInfo, BasePlayer initiator) {
                    ServerMgr.Instance.StartCoroutine(SpawnCoastalLocationCoroutine(spawningMonumentInfo, initiator));
                }
                static IEnumerator SpawnCoastalLocationCoroutine(SiteSpawnInfo spawningMonumentInfo, BasePlayer initiator) {
                    int counter = 25000;
                    BuildingSite site = null;
                    while (counter-- > 0) {
                        Vector3 position = PositionDefiner.GetRandomMapPoint();
                        position.y = 0;
                        if (IsPositionSuitable(ref position, ref spawningMonumentInfo, false, false)) {
                            site = SpawnSite(spawningMonumentInfo, position, spawningMonumentInfo.rotation, false);
                            break;
                        }
                        else if (counter % 10 == 0) yield return CoroutineEx.waitForEndOfFrame;
                    }
                    if (site == null) NotifyManagerLite.PrintInfoMessage(initiator, "CantFindPosition_Exeption", spawningMonumentInfo.config.presetName);
                }
                internal static BuildingSite TrySpawnLocation(Vector3 position, ref SiteSpawnInfo spawningMonumentInfo) {
                    if (IsPositionSuitable(ref position, ref spawningMonumentInfo, false, true)) {
                        return SpawnSite(spawningMonumentInfo, position, spawningMonumentInfo.rotation, true);
                    }
                    return null;
                }
                internal static bool IsPositionSuitable(ref Vector3 position, ref SiteSpawnInfo spawningMonumentInfo, bool ignorePlayers, bool isPlayerSummoned) {
                    Vector3 groundPosition = PositionDefiner.GetGroundPosition(position, 1 << 23);
                    position.y = 0;
                    float mapHeigth = TerrainMeta.HeightMap.GetHeight(position);
                    if (mapHeigth > 0 || mapHeigth < -30 || !TopologyChecker.IsPositionHaveTopology(position, (int)(TerrainTopology.Enum.Ocean | TerrainTopology.Enum.Oceanside))) {
                        spawningMonumentInfo.reasonOfFail = "FarShore_BlockSpawn";
                        return false;
                    }
                    if (!IsPositionInMapBounds(position, spawningMonumentInfo.config)) {
                        spawningMonumentInfo.reasonOfFail = "FarShore_BlockSpawn";
                        return false;
                    }
                    if (BuildingSite.IsSpawnPositionBlockByOtherSite(position, ref spawningMonumentInfo)) return false;
                    if (!isPlayerSummoned && !IsBiomeSuitable(position, ref spawningMonumentInfo)) return false;
                    if (PositionDefiner.IsPositionOnCargoPath(position)) {
                        spawningMonumentInfo.reasonOfFail = "Cargo_BlockSpawn";
                        return false;
                    }
                    if (IsPositionBlockedByTopology(position, ref spawningMonumentInfo)) return false;
                    if (IsAnyColliderBlockSpawn(position, ref spawningMonumentInfo, ignorePlayers)) return false;
                    Quaternion newRotation = GetShoreMonumentRotation(position);
                    spawningMonumentInfo.rotation = newRotation;
                    GameObject gameObject = new GameObject();
                    gameObject.transform.position = position;
                    gameObject.transform.rotation = newRotation;
                    foreach (string localPositionString in spawningMonumentInfo.data.checkPositions) {
                        Vector3 localPosition = localPositionString.ToVector3();
                        Vector3 globalPosition = PositionDefiner.GetGlobalPosition(gameObject.transform, localPosition);
                        if (IsPositionBlockByHeigth(position, globalPosition, spawningMonumentInfo.config.maxUpDeltaHeigh, spawningMonumentInfo.config.maxDownDeltaHeigh, spawningMonumentInfo.type)) {
                            spawningMonumentInfo.reasonOfFail = "UnsuitableLandscape_BlockSpawn";
                            UnityEngine.GameObject.Destroy(gameObject);
                            return false;
                        }
                    }
                    UnityEngine.GameObject.Destroy(gameObject);
                    return true;
                }
                static Quaternion GetShoreMonumentRotation(Vector3 position) {
                    float radius = 50f;
                    int angleStep = 10;
                    Vector3 maxYPosition = new Vector3(0, -10, 0);
                    for (int angle = 0; angle < 360; angle += angleStep) {
                        float radian = 2f * Mathf.PI * angle / 360;
                        float x = position.x + radius * Mathf.Cos(radian);
                        float z = position.z + radius * Mathf.Sin(radian);
                        Vector3 positionInRadius = PositionDefiner.GetGroundPosition(new Vector3(x, position.y, z), 1 << 23);
                        if (positionInRadius.y > maxYPosition.y) maxYPosition = positionInRadius;
                    }
                    if (maxYPosition == new Vector3(0, -10, 0)) return Quaternion.Euler(0, UnityEngine.Random.Range(0, 360f), 0);
                    position.y = 0;
                    maxYPosition.y = 0;
                    Vector3 direction = (maxYPosition - position).normalized;
                    return Quaternion.LookRotation(direction);
                }
            }
            static class WaterSpawner {
                internal static void SpawnInRandomPosition(SiteSpawnInfo spawningMonumentInfo, BasePlayer initiator) {
                    ServerMgr.Instance.StartCoroutine(SpawnWaterLocationCoroutine(spawningMonumentInfo, initiator));
                }
                static IEnumerator SpawnWaterLocationCoroutine(SiteSpawnInfo spawningMonumentInfo, BasePlayer initiator) {
                    int counter = 25000;
                    BuildingSite site = null;
                    while (counter-- > 0) {
                        Vector3 position = PositionDefiner.GetRandomMapPoint();
                        position.y = 0;
                        if (IsPositionSuitable(position, ref spawningMonumentInfo, false, false)) {
                            Quaternion rotation = Quaternion.Euler(0, UnityEngine.Random.Range(0, 360f), 0);
                            site = SpawnSite(spawningMonumentInfo, position, rotation, false);
                            break;
                        }
                        else if (counter % 10 == 0) yield return CoroutineEx.waitForEndOfFrame;
                    }
                    if (site == null) NotifyManagerLite.PrintInfoMessage(initiator, "CantFindPosition_Exeption", spawningMonumentInfo.config.presetName);
                }
                internal static BuildingSite TrySpawnLocation(Vector3 position, ref SiteSpawnInfo spawningMonumentInfo) {
                    position.y = 0;
                    if (IsPositionSuitable(position, ref spawningMonumentInfo, false, true)) {
                        Quaternion rotation = Quaternion.Euler(0, UnityEngine.Random.Range(0, 360f), 0);
                        return SpawnSite(spawningMonumentInfo, position, rotation, true);
                    }
                    return null;
                }
                internal static bool IsPositionSuitable(Vector3 position, ref SiteSpawnInfo spawningMonumentInfo, bool ignorePlayers, bool isPlayerSummoned) {
                    position.y = 0;
                    float mapHeigth = TerrainMeta.HeightMap.GetHeight(position);
                    if (-mapHeigth < ins._config.waterTypeConfig.minDepth) {
                        spawningMonumentInfo.reasonOfFail = "InsufficientDepth_BlockSpawn";
                        return false;
                    }
                    if (!IsPositionInMapBounds(position, spawningMonumentInfo.config)) {
                        spawningMonumentInfo.reasonOfFail = "FarShore_BlockSpawn";
                        return false;
                    }
                    if (BuildingSite.IsSpawnPositionBlockByOtherSite(position, ref spawningMonumentInfo)) return false;
                    if (!isPlayerSummoned && !IsBiomeSuitable(position, ref spawningMonumentInfo)) return false;
                    if (PositionDefiner.IsPositionOnCargoPath(position)) {
                        spawningMonumentInfo.reasonOfFail = "Cargo_BlockSpawn";
                        return false;
                    }
                    if (IsPositionBlockedByTopology(position, ref spawningMonumentInfo)) return false;
                    if (IsAnyColliderBlockSpawn(position, ref spawningMonumentInfo, ignorePlayers)) return false;
                    return true;
                }
            }
            static class GroundSpawner {
                internal static void SpawnInRandomPosition(SiteSpawnInfo spawningMonumentInfo, BasePlayer initiator) {
                    ServerMgr.Instance.StartCoroutine(SpawnGroundLocationCoroutine(spawningMonumentInfo, initiator));
                }
                static IEnumerator SpawnGroundLocationCoroutine(SiteSpawnInfo spawningMonumentInfo, BasePlayer initiator) {
                    int counter = 25000;
                    BuildingSite site = null;
                    while (counter-- > 0) {
                        Vector3 position = PositionDefiner.GetRandomMapPoint();
                        if (IsPositionSuitable(ref position, ref spawningMonumentInfo, false, false)) {
                            site = SpawnSite(spawningMonumentInfo, position, spawningMonumentInfo.rotation, false);
                            break;
                        }
                        else if (counter % 10 == 0) yield return CoroutineEx.waitForEndOfFrame;
                    }
                    if (site == null) NotifyManagerLite.PrintInfoMessage(initiator, "CantFindPosition_Exeption", spawningMonumentInfo.config.presetName);
                }
                internal static bool IsPositionSuitable(ref Vector3 position, ref SiteSpawnInfo spawningMonumentInfo, bool ignorePlayers, bool isPlayerSummoned) {
                    float mapHeigth = TerrainMeta.HeightMap.GetHeight(position);
                    if (position.y < -0.5f) return false;
                    if (BuildingSite.IsSpawnPositionBlockByOtherSite(position, ref spawningMonumentInfo)) return false;
                    if (!isPlayerSummoned && !IsBiomeSuitable(position, ref spawningMonumentInfo)) return false;
                    if (IsPositionBlockedByTopology(position, ref spawningMonumentInfo)) return false;
                    if (IsAnyColliderBlockSpawn(position, ref spawningMonumentInfo, ignorePlayers)) return false;
                    bool isSuitable = false;
                    Vector3 newPosition = position;
                    Vector3 offset = spawningMonumentInfo.data.offset.ToVector3();
                    for (int i = -10; i <= 10; i++) {
                        if (isSuitable) break;
                        Vector3 deltaPos = Vector3.up * i / 2;
                        if (spawningMonumentInfo.config.dataFileName == "bridge_1") deltaPos = -deltaPos;
                        newPosition = position + deltaPos;
                        if (newPosition.y + offset.y < 0.2f) continue;
                        if (spawningMonumentInfo.data.checkPositions == null || spawningMonumentInfo.data.checkPositions.Count == 0) {
                            if (IsPositionBlockByHeigthInRadius(newPosition, spawningMonumentInfo.config.internalRadius, spawningMonumentInfo.config.maxUpDeltaHeigh, spawningMonumentInfo.config.maxDownDeltaHeigh, spawningMonumentInfo.type)) continue;
                            if (IsPositionBlockByHeigthInRadius(newPosition, spawningMonumentInfo.config.internalRadius * 0.5f, spawningMonumentInfo.config.maxUpDeltaHeigh, spawningMonumentInfo.config.maxDownDeltaHeigh, spawningMonumentInfo.type)) continue;
                            isSuitable = true;
                            break;
                        }
                        else {
                            Quaternion newRotation = Quaternion.identity;
                            for (int angle = 0; angle < 360; angle += 90) {
                                newRotation = Quaternion.Euler(0, angle, 0);
                                GameObject gameObject = new GameObject();
                                gameObject.transform.position = newPosition;
                                gameObject.transform.rotation = newRotation;
                                bool isFailed = false;
                                foreach (string localPositionString in spawningMonumentInfo.data.checkPositions) {
                                    Vector3 localPosition = localPositionString.ToVector3();
                                    Vector3 globalPosition = PositionDefiner.GetGlobalPosition(gameObject.transform, localPosition);
                                    if (IsPositionBlockByHeigth(newPosition, globalPosition, spawningMonumentInfo.config.maxUpDeltaHeigh, spawningMonumentInfo.config.maxDownDeltaHeigh, spawningMonumentInfo.type)) {
                                        isFailed = true;
                                        break;
                                    }
                                }
                             
// ... [Code preview truncated due to length. Full source in attached file] ...

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