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

FREE Barges : 1.0.6 1.0.6

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using CompanionServer.Handlers;
using Facepunch;
using Network;
using Newtonsoft.Json;
using Oxide.Core;
using Oxide.Core.Plugins;
using Oxide.Plugins.BargesExtensionMethods;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
using UnityEngine.AI;
using static StabilityEntity;
namespace Oxide.Plugins {
    [Info("Barges", "Adem", "1.0.6")]
    class Barges : RustPlugin {
#region Variables
        const bool en = true;
        static Barges ins;
        [PluginReference]
        Plugin GUIAnnouncements, Notify, DiscordMessages;
        HashSet<string> subscribeMethods = new HashSet<string> {
            "OnButtonPress", "CanBuild", "CanPickupEntity", "CanChangeGrade", "OnStructureRotate", "OnStructureUpgraded", "OnConstructionPlace", "OnPoweredLightsPointAdd", "OnEntityStabilityCheck", "OnEntityKill", "OnEntitySpawned", "CanMountEntity", "OnEntityMounted", "OnHammerHit", "CanPickupEntity", "OnWireClear", "OnWireConnect", "OnExplosiveThrown", "OnEntityTakeDamage", "CanLootEntity", "CanEntityTakeDamage"
        }
        ;
#endregion Variables
#region Hooks
        void Init() {
            Unsubscribes();
        }
        void OnServerInitialized() {
            ins = this;
            UpdateConfig();
            if (!TryLoadData()) {
                NotifyManager.PrintError(null, "DataNotFound_Exeption");
                NextTick(() => Interface.Oxide.UnloadPlugin(Name));
                return;
            }
            LoadDefaultMessages();
            Subscribes();
            BoatConnectionTrigger.UpdateAllBoats();
            FishingVilageZoneController.CacheVilages();
            CargoShipManager.UpdateAllCargos();
            Barge.LoadBarges();
            BargeSpawner.StartPeriodicSpawn();
        }
        void Unload() {
            if (ins == null) return;
            Barge.SaveBarges(true);
            Barge.UnloadBarges();
            BargeSpawner.StopSpawning();
            BoatConnectionTrigger.Unload();
            FishingVilageZoneController.ClearZones();
            CargoShipManager.Unload();
            AdaptorInstallController.OnPluginUnload();
            ins = null;
        }
        void OnServerSave() {
            Barge.SaveBarges();
        }
        void OnButtonPress(PressButton button, BasePlayer player) {
            if (player == null || button == null) return;
            Barge barge = Barge.GetBargeByEntity(button);
            if (barge == null) return;
            BaseEntity parentEntity = button.GetParentEntity();
            if (parentEntity == null) return;
            BaseModule baseModule = parentEntity.GetComponentInChildren<BaseModule>();
            if (baseModule == null || !barge.IsPlayerCanInterract(player, true)) return;
            baseModule.OnButtonPressed(player);
        }
        object OnPlayerCommand(BasePlayer player, string command, string[] args) {
            if (player == null) return null;
            string checkClommand = command;
            foreach (string arg in args) checkClommand += $" {arg}";
            if (_config.mainConfig.blockedCommands.Any(x => x.ToLower() == checkClommand.ToLower())) {
                Barge barge = Barge.GetBargeByCollider(player);
                if (barge == null) return null;
                NotifyManager.SendMessageToPlayer(player, "BlockedOnBarge");
                return true;
            }
            return null;
        }
        object CanBuild(Planner planner, Construction prefab, Construction.Target constructionTarget) {
            if (planner == null || constructionTarget.entity == null) return null;
            BasePlayer player = planner.GetOwnerPlayer();
            if (player == null) return null;
            BaseEntity parentEntity = constructionTarget.entity.GetParentEntity();
            if (parentEntity == null || parentEntity.net == null) return null;
            Barge barge = Barge.GetBargeByParentEntityNetId(parentEntity.net.ID.Value);
            if (barge == null) {
                if (Barge.GetBargeByEntity(parentEntity)) return true;
                return null;
            }
            Item item = planner.GetItem();
            if (item != null && item.info != null && _config.mainConfig.bloskedItemShortnames.Contains(item.info.shortname)) {
                NotifyManager.SendMessageToPlayer(player, "BlockedOnBarge");
                return true;
            }
            if (!barge.IsPlayerCanInterract(player, true)) return true;
            if (planner.ShortPrefabName.Contains("wallpaper") || (prefab != null && prefab.deployable != null && (prefab.deployable.fullName.Contains("frankensteintable")))) {
                //|| prefab.deployable.fullName.Contains("electrical.modularcarlift.deployed")
                NotifyManager.SendMessageToPlayer(player, "BlockedOnBarge");
                return true;
            }
            if (!barge.IsPlayerCanBuild(player, true)) return true;
            return null;
        }
        object CanPickupEntity(BasePlayer player, BaseEntity entity) {
            if (player == null || entity == null) return null;
            Barge barge = Barge.GetBargeByEntity(entity);
            if (barge == null) {
                BuildingPrivlidge buildingPrivlidge = player.GetBuildingPrivilege();
                if (buildingPrivlidge != null && Barge.GetBargeByEntity(buildingPrivlidge) != null) {
                    BuildingPrivlidge entityBuildingPrivlidge = entity.GetBuildingPrivilege();
                    if (entityBuildingPrivlidge != null && !entityBuildingPrivlidge.IsAuthed(player)) return false;
                }
                return null;
            }
            if (!barge.IsPlayerCanInterract(player, false)) return false;
            return null;
        }
        object CanChangeGrade(BasePlayer player, BuildingBlock block, BuildingGrade.Enum grade) {
            if (player == null) return null;
            Barge barge = Barge.GetBargeByEntity(block);
            if (barge == null) return null;
            if (!barge.IsPlayerCanBuild(player, true)) return false;
            if (block.grade == grade && _config.performanceConfig.autoSkin) return false;
            if (barge.IsBasicBuildingBlock(block)) return false;
            if ((!ins._config.performanceConfig.allowStone && grade == BuildingGrade.Enum.Stone) || (!ins._config.performanceConfig.allowHqm && grade == BuildingGrade.Enum.TopTier)) {
                NotifyManager.SendMessageToPlayer(player, "BlockGrade");
                return false;
            }
            else if ((!ins._config.performanceConfig.allowMetall && grade == BuildingGrade.Enum.Metal) || (!ins._config.performanceConfig.allowWood && grade == BuildingGrade.Enum.Wood)) {
                return false;
            }
            return null;
        }
        object OnStructureRotate(BaseCombatEntity entity, BasePlayer player) {
            if (entity == null) return null;
            Barge barge = Barge.GetBargeByEntity(entity);
            if (barge == null) return null;
            if (!barge.IsStopped()) {
                NotifyManager.SendMessageToPlayer(player, "AnchorBarge");
                return true;
            }
            return null;
        }
        void OnStructureUpgraded(BuildingBlock buildingBlock, BasePlayer player, BuildingGrade.Enum grade, ulong skin) {
            if (buildingBlock == null) return;
            Barge barge = Barge.GetBargeByEntity(buildingBlock);
            if (barge == null) return;
            if (!_config.performanceConfig.autoSkin) return;
            if (grade == BuildingGrade.Enum.Wood && skin != 10232) {
                buildingBlock.ChangeGradeAndSkin(BuildingGrade.Enum.Wood, 10232, true);
            }
            else if (grade == BuildingGrade.Enum.Metal && skin != 10221) {
                buildingBlock.ChangeGradeAndSkin(BuildingGrade.Enum.Metal, 10221, true);
                buildingBlock.SetCustomColour(11);
            }
        }
        void OnConstructionPlace(BaseCombatEntity entity, Construction component, Construction.Target constructionTarget, BasePlayer player) {
            if (entity == null || constructionTarget.entity == null || player == null) return;
            BaseEntity parentEntity = constructionTarget.entity.GetParentEntity();
            if (parentEntity == null || parentEntity.net == null) return;
            Barge barge = Barge.GetBargeByParentEntityNetId(parentEntity.net.ID.Value);
            if (barge == null) return;
            barge.OnPlayerBuild(player, entity, constructionTarget.entity);
        }
        object OnPoweredLightsPointAdd(PoweredLightsDeployer poweredLightsDeployer, BasePlayer player, Vector3 vector31, Vector3 vector32) {
            if (player == null) return null;
            Barge barge = Barge.GetBargeByCollider(player);
            if (barge == null) return null;
            NotifyManager.SendMessageToPlayer(player, "BlockedOnBarge");
            return true;
        }
        object OnEntityStabilityCheck(BuildingBlock buildingBlock) {
            if (buildingBlock == null || buildingBlock.net == null) return null;
            Barge barge = Barge.GetBargeByEntity(buildingBlock);
            if (barge == null) return null;
            return true;
        }
        void OnEntityKill(BuildingBlock buildingBlock) {
            if (buildingBlock == null || buildingBlock.net == null) return;
            Barge barge = Barge.GetBargeByEntity(buildingBlock);
            if (barge == null) return;
            barge.Invoke(() => barge.shoudUpdateStability = true, 0.1f);
        }
        object OnEntityKill(SkyLantern skyLantern) {
            if (skyLantern == null || skyLantern.net == null) return null;
            Barge barge = Barge.GetBargeByParentEntityNetId(skyLantern.net.ID.Value);
            if (barge == null) return null;
            if (!barge.shoudKill) return true;
            return null;
        }
        void OnEntitySpawned(BaseBoat baseBoat) {
            if (baseBoat == null) return;
            BoatConnectionTrigger.TryAddBoatConnectionTrigger(baseBoat);
        }
        void OnEntitySpawned(CargoShip cargoShip) {
            if (cargoShip == null) return;
            CargoShipManager.AttachController(cargoShip);
        }
        void OnEntitySpawned(DecayEntity decayEntity) {
            CheckIfOtherPluginSpawnedEntity(decayEntity);
        }
        void OnEntitySpawned(Recycler recycler) {
            CheckIfOtherPluginSpawnedEntity(recycler);
        }
        void OnEntitySpawned(BasePortal basePortal) {
            CheckIfOtherPluginSpawnedEntity(basePortal);
        }
        void CheckIfOtherPluginSpawnedEntity(BaseEntity baseEntity) {
            if (baseEntity == null || baseEntity.HasParent()) return;
            if (baseEntity is StorageContainer && !baseEntity.enableSaving) return;
            Barge barge = Barge.GetBargeByCollider(baseEntity);
            if (barge == null) return;
            if (!barge.IsEntityShoudParrent(baseEntity) || barge.IsEntityShoutParentToTargetEntity(baseEntity)) return;
            baseEntity.SetParent(barge.mainEntity, true);
        }
        object CanMountEntity(BasePlayer player, BaseMountable baseMountable) {
            if (player == null || baseMountable == null) return null;
            if ((baseMountable is BaseVehicleSeat && baseMountable.ShortPrefabName != "arcadeuser") || baseMountable is MovableBaseMountable) return null;
            Barge barge = Barge.GetBargeByEntity(baseMountable);
            if (barge == null) {
                BaseEntity parentEntity = baseMountable.VehicleParent();
                if (parentEntity == null) return null;
                barge = Barge.GetBargeByEntity(parentEntity);
            }
            if (barge == null) return null;
            if (!barge.IsStopped()) {
                NotifyManager.SendMessageToPlayer(player, "BlockedWhileMoving");
                return true;
            }
            return null;
        }
        void OnEntityMounted(BaseMountable baseMountable, BasePlayer player) {
            if (baseMountable == null || player == null) return;
            BaseVehicle baseVehicle = baseMountable.VehicleParent();
            if (baseVehicle == null || !baseVehicle.IsDriver(player)) return;
            if (baseVehicle is not BaseBoat && baseVehicle is not BaseSubmarine) return;
            BaseEntity parentEntity = baseVehicle.GetParentEntity();
            if (parentEntity == null) return;
            Barge barge = Barge.GetBargeByEntity(parentEntity);
            if (barge == null) return;
            DockModule dockModule = parentEntity.GetComponentInChildren<DockModule>();
            if (dockModule == null || !barge.IsPlayerCanInterract(player, true)) return;
            dockModule.ReleaseBoat();
        }
        void OnHammerHit(BasePlayer player, HitInfo info) {
            if (player == null || info == null || info.HitEntity == null) return;
            if (info.HitEntity.ShortPrefabName != "coaling_tower_fuel_storage.entity") return;
            Barge barge = Barge.GetBargeByEntity(info.HitEntity);
            if (barge == null || barge.IsStopped()) return;
            BargePhysics bargePhysics = barge.GetBargePhysics();
            Vector3 pushDirection = (barge.transform.position - player.transform.position).normalized;
            pushDirection.y = 0;
            if (!barge.IsBargeOnShoal()) return;
            if (TerrainMeta.HeightMap.GetHeight(barge.transform.position + pushDirection) > TerrainMeta.HeightMap.GetHeight(barge.transform.position)) return;
            barge.StartMoving();
            bargePhysics.PushBarge(pushDirection);
        }
        object CanPickupEntity(BasePlayer player, SimpleLight simpleLight) {
            if (simpleLight == null || simpleLight.net == null) return null;
            Barge barge = Barge.GetBargeByEntity(simpleLight);
            if (barge == null) return null;
            if (simpleLight.GetParentEntity() is not DoorCloser) return null;
            return false;
        }
        object CanPickupEntity(BasePlayer player, PressButton preseButton) {
            if (preseButton == null) return null;
            if (preseButton.HasFlag(BaseEntity.Flags.InUse)) return false;
            return true;
        }
        object OnWireClear(BasePlayer player, IOEntity entity1, int connected, IOEntity entity2, bool flag) {
            if (entity1 == null || entity2 == null) return null;
            Barge barge = Barge.GetBargeByEntity(entity1);
            if (barge == null) barge = Barge.GetBargeByEntity(entity2);
            if (barge == null) return null;
            if (!barge.IsStopped()) {
                NotifyManager.SendMessageToPlayer(player, "BlockedWhileMoving");
                return true;
            }
            return null;
        }
        object OnWireConnect(BasePlayer player, IOEntity entity1, int inputs, IOEntity entity2, int outputs) {
            if (entity1 == null || entity2 == null) return null;
            Barge barge1 = Barge.GetBargeByEntity(entity1);
            Barge barge2 = Barge.GetBargeByEntity(entity2);
            if (barge1 != barge2) return true;
            if (barge1 == null) return null;
            if (!barge1.IsStopped()) {
                NotifyManager.SendMessageToPlayer(player, "BlockedWhileMoving");
                return true;
            }
            return null;
        }
        void OnExplosiveThrown(BasePlayer player, RoadFlare roadFlare, ThrownWeapon thrownWeapon) {
            if (!player.IsRealPlayer() || roadFlare == null || thrownWeapon == null) return;
            Item item = thrownWeapon.GetItem();
            if (item == null) return;
            BargeConfig bargeConfig = _config.bargeConfigs.FirstOrDefault(x => x.itemConfig.shortname == item.info.shortname && x.itemConfig.skin == item.skin);
            if (bargeConfig == null) return;
            BargeCaller.Attach(roadFlare, player, bargeConfig);
        }
        object OnEntityTakeDamage(SkyLantern skyLantern, HitInfo info) {
            if (skyLantern == null || info == null) return null;
            Barge barge = Barge.GetBargeByEntity(skyLantern);
            if (barge == null) return null;
            return true;
        }
        object OnEntityTakeDamage(BuildingBlock buildingBlock, HitInfo info) {
            if (buildingBlock == null || info == null) return null;
            Barge barge = Barge.GetBargeByEntity(buildingBlock);
            if (barge == null) return null;
            if (barge.IsBasicBuildingBlock(buildingBlock)) return true;
            return null;
        }
        object OnEntityTakeDamage(PressButton button, HitInfo info) {
            if (button == null || info == null) return null;
            Barge barge = Barge.GetBargeByEntity(button);
            if (barge == null) return null;
            BaseEntity parentEntity = button.GetParentEntity();
            if (parentEntity == null) return null;
            BaseModule baseModule = parentEntity.GetComponentInChildren<BaseModule>();
            if (baseModule == null) return null;
            return true;
        }
        object OnEntityTakeDamage(BaseBoat baseBoat, HitInfo info) {
            if (baseBoat == null || info == null) return null;
            BaseEntity parentEntity = baseBoat.GetParentEntity();
            if (parentEntity == null || parentEntity.net == null) return null;
            Barge barge = Barge.GetBargeByEntity(parentEntity);
            if (barge == null) return null;
            if (info.damageTypes.GetMajorityDamageType() == DamageType.Decay) return true;
            return null;
        }
        object OnEntityTakeDamage(BaseSubmarine baseSubmarine, HitInfo info) {
            if (baseSubmarine == null || info == null) return null;
            BaseEntity parentEntity = baseSubmarine.GetParentEntity();
            if (parentEntity == null || parentEntity.net == null) return null;
            Barge barge = Barge.GetBargeByEntity(parentEntity);
            if (barge == null) return null;
            if (info.damageTypes.GetMajorityDamageType() == DamageType.Decay) return true;
            return null;
        }
        object CanLootEntity(BasePlayer player, ResourceExtractorFuelStorage container) {
            if (container == null || player == null) return null;
            Barge barge = Barge.GetBargeByEntity(container);
            if (barge == null) return null;
            if (container.GetParentEntity() is DoorCloser && !barge.IsPlayerCanInterract(player, true)) return true;
            return null;
        }
        void OnActiveItemChanged(BasePlayer player, Item oldItem, Item newItem) {
            if (!player.IsRealPlayer() || newItem == null) return;
            if (newItem.info.shortname == "storageadaptor") AdaptorInstallController.TryAttachController(player);
        }
        object CanEntityTakeDamage(SkyLantern skyLantern, HitInfo info) {
            if (skyLantern == null || info == null) return null;
            Barge barge = Barge.GetBargeByEntity(skyLantern);
            if (barge == null) return null;
            return false;
        }
        object CanEntityTakeDamage(BuildingBlock buildingBlock, HitInfo info) {
            if (buildingBlock == null || info == null) return null;
            Barge barge = Barge.GetBargeByEntity(buildingBlock);
            if (barge == null) return null;
            if (barge.IsBasicBuildingBlock(buildingBlock)) return false;
            return null;
        }
        object CanEntityTakeDamage(PressButton button, HitInfo info) {
            if (button == null || info == null) return null;
            Barge barge = Barge.GetBargeByEntity(button);
            if (barge == null) return null;
            BaseEntity parentEntity = button.GetParentEntity();
            if (parentEntity == null) return null;
            BaseModule baseModule = parentEntity.GetComponentInChildren<BaseModule>();
            if (baseModule == null) return null;
            return false;
        }
        object CanEntityTakeDamage(BaseBoat baseBoat, HitInfo info) {
            if (baseBoat == null || info == null) return null;
            BaseEntity parentEntity = baseBoat.GetParentEntity();
            if (parentEntity == null || parentEntity.net == null) return null;
            Barge barge = Barge.GetBargeByEntity(parentEntity);
            if (barge == null) return null;
            if (info.damageTypes.GetMajorityDamageType() == DamageType.Decay) return false;
            return null;
        }
        object CanEntityTakeDamage(BaseSubmarine baseSubmarine, HitInfo info) {
            if (baseSubmarine == null || info == null) return null;
            BaseEntity parentEntity = baseSubmarine.GetParentEntity();
            if (parentEntity == null || parentEntity.net == null) return null;
            Barge barge = Barge.GetBargeByEntity(parentEntity);
            if (barge == null) return null;
            if (info.damageTypes.GetMajorityDamageType() == DamageType.Decay) return false;
            return null;
        }
#endregion Hooks
#region Commands
        [ChatCommand("spawnbarge")]
        void ChatSpawnBargeCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            string bargePreset = "";
            if (arg.Length > 0) bargePreset = arg[0];
            Barge.SpawnBarge(player.transform.position, Quaternion.identity, bargePreset, false);
        }
        [ChatCommand("killbarge")]
        void ChatKillCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            BaseEntity target = RaycastAll<BaseEntity>(player.eyes.HeadRay());
            if (target == null) return;
            Barge barge = Barge.GetBargeByEntity(target);
            if (barge == null) return;
            barge.KillBarge();
        }
        [ChatCommand("killallbarges")]
        void ChatKillAllCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
            Barge.KillAllBarges();
        }
        [ChatCommand("bargetest")]
        void ChatTestCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin) return;
        }
        [ChatCommand("givebarge")]
        void ChatGiveBargeCommand(BasePlayer player, string command, string[] arg) {
            if (!player.IsAdmin || arg.Length < 1) return;
            string presetName = arg[0];
            BargeConfig bargeConfig = _config.bargeConfigs.FirstOrDefault(x => x.presetName == presetName);
            if (bargeConfig == null) {
                NotifyManager.PrintError(player, "ConfigNotFound_Exeption", presetName);
                return;
            }
            LootManager.GiveItemToPLayer(player, bargeConfig.itemConfig, 1);
            NotifyManager.SendMessageToPlayer(player, "GotBarge");
        }
        [ConsoleCommand("givebarge")]
        void ConsoleGiveBargeCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null || arg.Args.Length < 2) return;
            string presetName = arg.Args[0];
            BargeConfig bargeConfig = _config.bargeConfigs.FirstOrDefault(x => x.presetName == presetName);
            if (bargeConfig == null) {
                NotifyManager.PrintError(null, "ConfigNotFound_Exeption", presetName);
                return;
            }
            ulong targetUserId = Convert.ToUInt64(arg.Args[1]);
            BasePlayer targetPlayer = BasePlayer.FindByID(targetUserId);
            if (targetPlayer == null) {
                NotifyManager.PrintError(null, "PlayerNotFound_Exeption", arg.Args[1]);
                return;
            }
            LootManager.GiveItemToPLayer(targetPlayer, bargeConfig.itemConfig, 1);
            NotifyManager.SendMessageToPlayer(targetPlayer, "GotBarge");
        }
        [ConsoleCommand("savebarge")]
        void ConsoleSaveBargeCommand(ConsoleSystem.Arg arg) {
            if (arg.Player() != null) return;
            MapSaver.CreateOrAddNewData("new");
        }
#endregion Commands
#region Methods
        void UpdateConfig() {
            if (_config.version != Version) {
                PluginConfig defaultConfig = PluginConfig.DefaultConfig();
                if (_config.version.Patch <= 1) {
                    foreach (BargeConfig bargeConfig in _config.bargeConfigs) {
                        bargeConfig.engineConfig.rotateScale = 1f;
                    }
                }
                if (_config.version.Patch <= 4) {
                    _config.mainConfig.blockedCommands = defaultConfig.mainConfig.blockedCommands;
                }
                _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);
        }
        BaseEntity RaycastAll<T>(Ray ray, float distance = 50) where T : BaseEntity {
            RaycastHit[] hits = Physics.RaycastAll(ray);
            GamePhysics.Sort(hits);
            BaseEntity target = null;
            foreach (RaycastHit hit in hits) {
                BaseEntity ent = hit.GetEntity();
                if (ent is T && hit.distance < distance) {
                    target = ent;
                    break;
                }
            }
            return target;
        }
#endregion Methods
#region Classes
        static class BargeSpawner {
            static Coroutine spawnCorountine;
            static HashSet<SpawnPositionInfo> spawnLocations = new HashSet<SpawnPositionInfo>();
            internal static void StartPeriodicSpawn() {
                if (!ins._config.spawnConfig.isSpawnEnabled) return;
                CacheSuitableMonuments();
                if (spawnLocations.Count == 0) return;
                spawnCorountine = ServerMgr.Instance.StartCoroutine(SpawnCorountine());
            }
            static void CacheSuitableMonuments() {
                spawnLocations = new HashSet<SpawnPositionInfo>();
                foreach (MonumentInfo monumentInfo in TerrainMeta.Path.Monuments) {
                    if (monumentInfo == null || monumentInfo.transform == null) continue;
                    SpawnMonumentConfig spawnMonumentConfig = ins._config.spawnConfig.monuments.FirstOrDefault(x => x.isEnabled && x.monumentName == monumentInfo.name);
                    if (spawnMonumentConfig == null) continue;
                    SaveMonumentPositions(monumentInfo, spawnMonumentConfig);
                }
            }
            static void SaveMonumentPositions(MonumentInfo monumentInfo, SpawnMonumentConfig spawnMonumentConfig) {
                foreach (LocationConfig locationConfig in spawnMonumentConfig.locations) {
                    Vector3 localPosition = locationConfig.position.ToVector3();
                    Vector3 localRotation = locationConfig.rotation.ToVector3();
                    Vector3 globalPosition = PositionDefiner.GetGlobalPosition(monumentInfo.transform, localPosition);
                    Quaternion globalRotation = PositionDefiner.GetGlobalRotation(monumentInfo.transform, localRotation);
                    SpawnPositionInfo spawnPositionInfo = new SpawnPositionInfo(globalPosition, globalRotation);
                    spawnLocations.Add(spawnPositionInfo);
                }
            }
            static IEnumerator SpawnCorountine() {
                while (true) {
                    yield return CoroutineEx.waitForSeconds(UnityEngine.Random.Range(ins._config.spawnConfig.minSpawnTime, ins._config.spawnConfig.maxSpawnTime));
                    List<SpawnPositionInfo> suitablePositions = Pool.Get<List<SpawnPositionInfo>>();
                    foreach (SpawnPositionInfo suitablePosition in spawnLocations) if (IsPositionSuitable(suitablePosition.position)) suitablePositions.Add(suitablePosition);
                    if (suitablePositions.Count > 0) {
                        SpawnPositionInfo spawnPositionInfo = suitablePositions.GetRandom();
                        SpawnBarge(spawnPositionInfo);
                    }
                    Pool.FreeUnmanaged(ref suitablePositions);
                }
            }
            static void SpawnBarge(SpawnPositionInfo spawnPositionInfo) {
                if (Barge.GetBargePopulation(true) >= ins._config.spawnConfig.maxBargeCount) return;
                string bargePresetName = GetRandomBargePreset();
                if (bargePresetName == null) return;
                Barge.SpawnBarge(spawnPositionInfo.position, spawnPositionInfo.rotation, bargePresetName, true);
            }
            static string GetRandomBargePreset() {
                float sumChance = 0;
                foreach (var pair in ins._config.spawnConfig.probabilities) sumChance += pair.Value;
                float random = UnityEngine.Random.Range(0, sumChance);
                foreach (var pair in ins._config.spawnConfig.probabilities) {
                    random -= pair.Value;
                    if (random <= 0) return pair.Key;
                }
                return null;
            }
            static bool IsPositionSuitable(Vector3 position) {
                if (Barge.barges.Any(x => x != null && Vector3.Distance(x.transform.position, position) < 40f)) return false;
                HashSet<BaseEntity> entitiesForKill = new HashSet<BaseEntity>();
                foreach (Collider collider in UnityEngine.Physics.OverlapSphere(position, 20f)) {
                    if (collider == null) continue;
                    BaseEntity entity = collider.ToBaseEntity();
                    if (entity == null) continue;
                    if (entity is BaseBoat or BaseSubmarine or CargoShip or BasePlayer) return false;
                    else if (entity is JunkPile or DiveSite) entitiesForKill.Add(entity);
                }
                foreach (BaseEntity entity in entitiesForKill) if (entity.IsExists()) entity.Kill();
                return true;
            }
            internal static void StopSpawning() {
                if (spawnLocations != null) {
                    spawnLocations.Clear();
                    spawnLocations = null;
                }
                if (spawnCorountine != null) ServerMgr.Instance.StopCoroutine(spawnCorountine);
                spawnCorountine = null;
            }
        }
        class SpawnPositionInfo {
            internal Vector3 position;
            internal Quaternion rotation;
            internal SpawnPositionInfo(Vector3 position, Quaternion rotation) {
                this.position = position;
                this.rotation = rotation;
            }
        }
        class FishingVilageZoneController : FacepunchBehaviour {
            static HashSet<FishingVilageZoneController> zoneControllers = new HashSet<FishingVilageZoneController>();
            SphereCollider sphereCollider;
            const float zoneRadius = 55;
            internal static void CacheVilages() {
                if (!ins._config.mainConfig.blockFishingVillage) return;
                foreach (MonumentInfo monumentInfo in TerrainMeta.Path.Monuments) {
                    if (monumentInfo.name.Contains("fishing")) {
                        GameObject gameObject = new GameObject("FishingVilageZoneController");
                        gameObject.layer = (int)Rust.Layer.Reserved1;
                        gameObject.transform.position = monumentInfo.transform.position;
                        FishingVilageZoneController zoneController = gameObject.AddComponent<FishingVilageZoneController>();
                        FishingVilageZoneController.zoneControllers.Add(zoneController);
                    }
                }
            }
            void Awake() {
                sphereCollider = gameObject.AddComponent<SphereCollider>();
                sphereCollider.isTrigger = true;
                sphereCollider.radius = zoneRadius;
            }
            void OnTriggerEnter(Collider other) {
                if (other == null) return;
                BaseEntity entity = other.ToBaseEntity();
                if (entity == null || entity.net == null || entity.ShortPrefabName != "kayak") return;
                Barge barge = Barge.GetBargeByPhysicsEntityNetId(entity.net.ID.Value);
                if (barge == null) return;
                BargePhysics bargePhysics = barge.GetBargePhysics();
                bargePhysics.OnBargeEnterToBlockZoneZone(transform.position);
            }
            internal static void ClearZones() {
                foreach (FishingVilageZoneController zoneController in zoneControllers) if (zoneController != null) zoneController.DeleteZone();
            }
            void DeleteZone() {
                Destroy(this.gameObject);
            }
        }
        class BuildingVisibilityManager : FacepunchBehaviour {
            static HashSet<BuildingVisibilityManager> buildingVisibilityUpdaters = new HashSet<BuildingVisibilityManager>();
            static HashSet<BuildingBlockModelInfo> buildingBlockModelInfos = new HashSet<BuildingBlockModelInfo> {
                new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/wall/wall.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        9, 17, 25
                    }
                    , goodModelState = 1
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/roof/roof.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        12, 20, 28, 36, 44, 60, 68, 76, 84, 92, 100, 108, 124
                    }
                    , goodModelState = 4
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/roof/roof.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        8228, 8260, 8292, 24620, 24652, 24684, 24588,
                    }
                    , goodModelState = 8196
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/roof/roof.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        32852, 32788, 32836, 98316, 98332, 98380, 98396
                    }
                    , goodModelState = 32772
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/roof/roof.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        33, 65, 97
                    }
                    , goodModelState = 1
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/roof/roof.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        18, 66, 82
                    }
                    , goodModelState = 2
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/roof/roof.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        67
                    }
                    , goodModelState = 3
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/roof.triangle/roof.triangle.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        3, 5, 7, 9, 11, 13, 15
                    }
                    , goodModelState = 1
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/roof.triangle/roof.triangle.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        25, 49, 51, 57, 59, 8392713
                    }
                    , goodModelState = 17
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/wall.half/wall.half.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        1, 2, 3
                    }
                    , goodModelState = 0
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/wall.low/wall.low.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        1, 2, 3
                    }
                    , goodModelState = 0
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/wall.window/wall.window.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        1, 2
                    }
                    , goodModelState = 0
                }
                , new BuildingBlockModelInfo {
                    prefab = "assets/prefabs/building core/wall.doorway/wall.doorway.prefab", grade = BuildingGrade.Enum.Metal, badModelStates = new HashSet<int> {
                        1, 2
                    }
                    , goodModelState = 0
                }
            }
            ;
            BaseEntity parentEntity;
            Coroutine badBuildingBlocksCorountine;
            Coroutine goodBuildingBlocksCorountine;
            HashSet<BuildingBlock> badBuildingBlocks = new HashSet<BuildingBlock>();
            HashSet<BuildingBlock> goodBuildingBlocks = new HashSet<BuildingBlock>();
            int updatesPerTick;
            internal HashSet<IoEntitySaveData> ioEntitySaveDatas = new HashSet<IoEntitySaveData>();
            internal static void UpdateBuildingBlockVisibility(BuildingBlock buildingBlock) {
                if (buildingBlock.net.group.subscribers.Count == 0) return;
                NetWrite newWrite = Net.sv.StartWrite();
                newWrite.PacketID(Message.Type.RPCMessage);
                newWrite.EntityID(buildingBlock.net.ID);
                newWrite.UInt32(StringPool.Get("RefreshSkin"));
                newWrite.UInt64(0);
                newWrite.Send(new SendInfo(buildingBlock.net.group.subscribers));
            }
            internal static BuildingVisibilityManager AttachVisibilityUpdater(BaseEntity parentEntity) {
                GameObject triggerGameObject = new GameObject("BuildingVisibilityUpdater");
                triggerGameObject.transform.SetParent(parentEntity.transform, false);
                BuildingVisibilityManager buildingVisibilityUpdater = triggerGameObject.AddComponent<BuildingVisibilityManager>();
                buildingVisibilityUpdater.Init(parentEntity);
                buildingVisibilityUpdaters.Add(buildingVisibilityUpdater);
                return buildingVisibilityUpdater;
            }
            internal void UpdateBuildingBlockModels() {
                foreach (BaseEntity entity in parentEntity.children) {
                    BuildingBlock buildingBlock = entity as BuildingBlock;
                    if (buildingBlock != null) {
                        UpdateBuildingBlockModel(buildingBlock);
                    }
                }
            }
            static void DefineUpdateFrequency() {
                buildingVisibilityUpdaters.RemoveWhere(x => x == null);
                int sumBadBuildinbBlocksCount = 0;
                foreach (BuildingVisibilityManager buildingVisibilityUpdater in buildingVisibilityUpdaters) if (buildingVisibilityUpdater != null) sumBadBuildinbBlocksCount += buildingVisibilityUpdater.badBuildingBlocks.Count;
                foreach (BuildingVisibilityManager buildingVisibilityUpdater in buildingVisibilityUpdaters) {
                    if (buildingVisibilityUpdater == null) continue;
                    buildingVisibilityUpdater.updatesPerTick = sumBadBuildinbBlocksCount == 0 ? 0 : buildingVisibilityUpdater.badBuildingBlocks.Count * ins._config.performanceConfig.updatePerTick / sumBadBuildinbBlocksCount;
                    if (buildingVisibilityUpdater.updatesPerTick > buildingVisibilityUpdater.badBuildingBlocks.Count) buildingVisibilityUpdater.updatesPerTick = buildingVisibilityUpdater.badBuildingBlocks.Count;
                }
            }
            void Init(BaseEntity parentEntity) {
                this.parentEntity = parentEntity;
            }
            internal void OnStartMoving() {
                badBuildingBlocks.Clear();
                goodBuildingBlocks.Clear();
                ioEntitySaveDatas.Clear();
                foreach (BaseEntity entity in parentEntity.children) {
                    BuildingBlock buildingBlock = entity as BuildingBlock;
                    if (buildingBlock != null) {
                        CacheBuildingBlock(buildingBlock);
                        continue;
                    }
                    IOEntity iOEntity = entity as IOEntity;
                    if (iOEntity != null) {
                        CacheIOEntity(iOEntity);
                        continue;
                    }
                    if (entity is DoorCloser) {
                        foreach (BaseEntity subChildren in entity.children) {
                            BuildingBlock subBuildingBlock = subChildren as BuildingBlock;
                            if (subBuildingBlock != null) CacheBuildingBlock(subBuildingBlock);
                        }
                    }
                }
                StopCorountines();
                badBuildingBlocksCorountine = ServerMgr.Instance.StartCoroutine(BadBuildingBlocksCorountine());
                goodBuildingBlocksCorountine = ServerMgr.Instance.StartCoroutine(GoodBuildingBlocksCorountine());
                DefineUpdateFrequency();
            }
            void CacheBuildingBlock(BuildingBlock buildingBlock) {
                UpdateBuildingBlockModel(buildingBlock);
                if (IsBuildingBlockGoodMoving(buildingBlock)) goodBuildingBlocks.Add(buildingBlock);
                else badBuildingBlocks.Add(buildingBlock);
            }
            void UpdateBuildingBlockModel(BuildingBlock buildingBlock) {
                BuildingBlockModelInfo buildingBlockModelInfo = buildingBlockModelInfos.FirstOrDefault(x => x.prefab == buildingBlock.PrefabName && x.badModelStates.Contains(buildingBlock.modelState));
                if (buildingBlockModelInfo == null) return;
                buildingBlock.SetConditionalModel(buildingBlockModelInfo.goodModelState);
                buildingBlock.SendNetworkUpdate();
            }
            bool IsBuildingBlockGoodMoving(BuildingBlock buildingBlock) {
                if (buildingBlock.grade == BuildingGrade.Enum.Wood && buildingBlock.skinID == 10232) return true;
                if (buildingBlock.grade == BuildingGrade.Enum.Metal && buildingBlock.skinID == 10221) {
                    if (buildingBlock.ShortPrefabName.Contains("floor")) return false;
                    else return true;
                }
                return false;
            }
            void CacheIOEntity(IOEntity iOEntity) {
                HashSet<IOSlotData> inputSlotDatas = new HashSet<IOSlotData>();
                HashSet<IOSlotData> outputSlotDatas = new HashSet<IOSlotData>();
                foreach (var input in iOEntity.inputs) {
                    IOSlotData iOSlotData = GetSlotData(input);
                    inputSlotDatas.Add(iOSlotData);
                }
                foreach (var output in iOEntity.outputs) {
                    IOSlotData iOSlotData = GetSlotData(output);
                    outputSlotDatas.Add(iOSlotData);
                }
                iOEntity.SendNetworkUpdate();
                if (inputSlotDatas.Count == 0 && outputSlotDatas.Count == 0) return;
                IoEntitySaveData ioEntitySaveData = new IoEntitySaveData(iOEntity.net.ID.Value, inputSlotDatas, outputSlotDatas);
                ioEntitySaveDatas.Add(ioEntitySaveData);
            }
            IOSlotData GetSlotData(IOEntity.IOSlot slot) {
                HashSet<Vector3> linePoints = new HashSet<Vector3>();
                if (slot.linePoints != null) foreach (Vector3 localPosition in slot.linePoints) linePoints.Add(localPosition);
                slot.linePoints = new Vector3[1] {
                    Vector3.up
                }
                ;
                return new IOSlotData(linePoints);
            }
            IEnumerator BadBuildingBlocksCorountine() {
                while (true) {
                    int updatesInFrame = updatesPerTick;
                    foreach (BuildingBlock buildingBlock in badBuildingBlocks) {
                        if (!buildingBlock.IsExists() || buildingBlock.IsDead()) continue;
                        updatesInFrame--;
                        UpdateBuildingBlockVisibility(buildingBlock);
                        if (updatesInFrame <= 0) {
                            updatesInFrame = updatesPerTick;
                            yield return CoroutineEx.waitForSeconds(0.05f);
                        }
                    }
                    yield return CoroutineEx.waitForSeconds(0.05f);
                }
            }
            IEnumerator GoodBuildingBlocksCorountine() {
                while (true) {
                    foreach (BuildingBlock buildingBlock in goodBuildingBlocks) {
                        if (!buildingBlock.IsExists() || buildingBlock.IsDead()) continue;
                        UpdateBuildingBlockVisibility(buildingBlock);
                        yield return CoroutineEx.waitForSeconds(0.025f);
                    }
                    yield return CoroutineEx.waitForSeconds(2.5f);
                }
            }
            internal void OnStopMoving() {
                StopCorountines();
                foreach (BaseEntity entity in parentEntity.children) {
                    BuildingBlock buildingBlock = entity as BuildingBlock;
                    if (buildingBlock != null && buildingBlock.net != null) {
                        if (IsBuildingBlockGoodMoving(buildingBlock) && !buildingBlock.ShortPrefabName.Contains("stair")) {
                            UpdateBuildingBlockVisibility(buildingBlock);
                        }
                        buildingBlock.limitNetworking = true;
                        buildingBlock.limitNetworking = false;
                        buildingBlock.SetConditionalModel(buildingBlock.currentSkin.DetermineConditionalModelState(buildingBlock));
                        buildingBlock.SendNetworkUpdate();
                        continue;
             
// ... [Code preview truncated due to length. Full source in attached file] ...

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