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

FREE RustTanic : 1.0.3 1.0.3

Нет прав для скачивания
C#:
// Plugin formatted by redBDGR's Plugin Formatting Tool
using Oxide.Core;
using Rust;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Reflection;
using Oxide.Core.Configuration;
namespace Oxide.Plugins
{
    [Info("RustTanic", "redBDGR", "1.0.3f")]
    [Description("Server event for the Cargo Ship Модернизация от Ernieleo")]
    class RustTanic : RustPlugin
    {
        private bool Changed = false;
        private static RustTanic plugin;
        private TitanicManager manager;
        private int worldLayer = LayerMask.GetMask("World");
        private int defaultLayer = LayerMask.GetMask("Default");
        private FieldInfo tooHotUntil = typeof(HelicopterDebris).GetField("tooHotUntil", (BindingFlags.Instance | BindingFlags.NonPublic));
        private const string permissionNameADMIN = "rusttanic.admin";
        private List<ItemInfo> floatingCrateTable = new List<ItemInfo>();
        private List<ItemInfo> icebergCrateTable = new List<ItemInfo>();

        private class ConfigFile
        {
            public static float sequencingGaps = 60f;
            public static float spawnDistance = 3f;
            public static float boatSpeed = 1f;
            public static bool disableIcebergsWithCupboard = true;
            public static bool disableIcebergsWithBuilding = true;
            public static bool debugMode = false;
            public static int floatingCratesToSpawn = 7;
            public static float floatingCratesRadius = 30f;
            public static float floatingCrateDespawnTime = 900f;
            public static int floatingCrateMinItems = 3;
            public static int floatingCrateMaxItems = 6;
            public static int debisToSpawn = 4;
            public static int lootPerDebris = 1;
            public static float hackableCrateSeconds = 60f;
            public static bool spawnIcebergCrates = true;
            public static int icebergCratesToSpawn = 3;
            public static float icebergCratesSpawnRadius = 6f;
            public static string icebergCratePrefab = "assets/bundled/prefabs/radtown/crate_elite.prefab";
            public static int icebergCrateMinItems = 3;
            public static int icebergCrateMaxItems = 5;
            public static bool killBoatScientists = true;
            public static int icebergNPCToSpawn = 5;
            public static float icebergNPCSpawnRadius = 10f;
            public static string icebergNPCType = "assets/prefabs/npc/scientist/scientist.prefab";
            public static string icebergNPCNames = "Pirate";
            public static bool boatExhaustFlames = true;
            public static bool boatRotatingLights = true;
            public static bool disableExtraEffects = false;
            public static float boatHornInterval = 20f;
            public static bool randomEventEnabled = true;
            public static float minRandomEventTime = 7200f;
            public static float maxRandomEventTime = 10800;
            public static int minPlayersForEvent = 1;
            public static bool targetIcebergMarkerEnabled = true;
            public static float targetIcebergMarkerRadius = 20f;
            public static string targetIcerbergText = "Предположительное место крушения";
        }

        private void LoadVariables()
        {
            ConfigFile.sequencingGaps = Convert.ToSingle(GetConfig("Settings", "Задержка между этапами погружения", 60f));
            ConfigFile.spawnDistance = Convert.ToSingle(GetConfig("Settings", "Расстояние спавна", 2f));
            ConfigFile.boatSpeed = Convert.ToSingle(GetConfig("Settings", "Скорость хода", 1f));
            ConfigFile.debugMode = Convert.ToBoolean(GetConfig("Settings", "DebugMode", false));
            ConfigFile.disableIcebergsWithCupboard = Convert.ToBoolean(GetConfig("Settings", "Отключить Айсберги с билдинг шкафами", true));
            ConfigFile.disableIcebergsWithBuilding = Convert.ToBoolean(GetConfig("Settings", "Отключить Айсберги с строениями", true));
            ConfigFile.hackableCrateSeconds = Convert.ToSingle(GetConfig("General Loot", "Таймер взлома ящика", 60f));
            ConfigFile.spawnIcebergCrates = Convert.ToBoolean(GetConfig("Iceberg Loot", "Спавн ящиков на Айсберге", true));
            ConfigFile.icebergCratesToSpawn = Convert.ToInt16(GetConfig("Iceberg Loot", "Кол-во ящиков на Айсберге", 3));
            ConfigFile.icebergCratesSpawnRadius = Convert.ToSingle(GetConfig("Iceberg Loot", "Радиус спавна ящиков", 6f));
            ConfigFile.icebergCratePrefab = Convert.ToString(GetConfig("Iceberg Loot", "Prefab ящика", "assets/bundled/prefabs/radtown/crate_elite.prefab"));
            ConfigFile.icebergCrateMinItems = Convert.ToInt32(GetConfig("Iceberg Loot", "Минимум предметов в ящике", 3));
            ConfigFile.icebergCrateMaxItems = Convert.ToInt32(GetConfig("Iceberg Loot", "Максимум предметов в ящике", 5));
            ConfigFile.floatingCratesToSpawn = Convert.ToInt32(GetConfig("Floating Crates", "Кол-во плавающих ящиков", 7));
            ConfigFile.floatingCratesRadius = Convert.ToSingle(GetConfig("Floating Crates", "Радиус зоны плавающих ящиков", 30f));
            ConfigFile.floatingCrateDespawnTime = Convert.ToSingle(GetConfig("Floating Crates", "Время исчезновения плавающих ящиков", 900f));
            ConfigFile.floatingCrateMinItems = Convert.ToInt32(GetConfig("Floating Crates", "Минимум предметов в ящике", 4));
            ConfigFile.floatingCrateMaxItems = Convert.ToInt32(GetConfig("Floating Crates", "Максимум предметов в ящике", 6));
            ConfigFile.debisToSpawn = Convert.ToInt32(GetConfig("Debris", "Хлам для спавна", 4));
            ConfigFile.lootPerDebris = Convert.ToInt32(GetConfig("Debris", "Добыча за 1 хлам", 1));
            ConfigFile.icebergNPCToSpawn = Convert.ToInt32(GetConfig("NPCs", "Кол-во NPC на Айсберге", 5));
            ConfigFile.killBoatScientists = Convert.ToBoolean(GetConfig("NPCs", "Уничтожить лодку с Титаника", true));
            ConfigFile.icebergNPCSpawnRadius = Convert.ToSingle(GetConfig("NPCs", "Зона спавна NPC на Айсберге", 10f));
            ConfigFile.icebergNPCType = Convert.ToString(GetConfig("NPCs", "Тип NPC на Айсберге", "assets/prefabs/npc/scientist/scientist.prefab"));
            ConfigFile.icebergNPCNames = Convert.ToString(GetConfig("NPCs", "Имя NPC с Айсберга", "Pirate"));
            ConfigFile.boatExhaustFlames = Convert.ToBoolean(GetConfig("Visuals", "Пламя из выхлопной трубы", false));
            ConfigFile.boatRotatingLights = Convert.ToBoolean(GetConfig("Visuals", "Вращающиеся сигнальные огни", true));
            ConfigFile.disableExtraEffects = Convert.ToBoolean(GetConfig("Visuals", "Отключить все супер эффекты", false));
            ConfigFile.boatHornInterval = Convert.ToSingle(GetConfig("Visuals", "Интервал гудков", 20f));
            ConfigFile.minRandomEventTime = Convert.ToSingle(GetConfig("Timer Settings", "Минимальное время вызова ивента(сек)", 9000f));
            ConfigFile.maxRandomEventTime = Convert.ToSingle(GetConfig("Timer Settings", "Максимальное время вызова ивента(сек)", 10800f));
            ConfigFile.randomEventEnabled = Convert.ToBoolean(GetConfig("Timer Settings", "Рандом спавн в промежуток времени", true));
            ConfigFile.minPlayersForEvent = Convert.ToInt32(GetConfig("Timer Settings", "Минимальный онлайн на сервере", 1));
            ConfigFile.targetIcebergMarkerEnabled = Convert.ToBoolean(GetConfig("Marker Settings", "Точка крушения на карте", true));
            ConfigFile.targetIcebergMarkerRadius = Convert.ToSingle(GetConfig("Marker Settings", "Радиус места крушения", 1f));
            ConfigFile.targetIcerbergText = Convert.ToString(GetConfig("Marker Settings", "Название места крушения", "Предположительное место крушения"));
            if (!Changed) return;
            SaveConfig();
            Changed = false;
        }
        protected override void LoadDefaultConfig()
        {
            Config.Clear();
            LoadVariables();
        }
        private DynamicConfigFile floatingCrateFile;
        private DynamicConfigFile icebergCrateFile;
        StoredData storedData;
        private class StoredData
        {
            public List<ItemInfo> lootTable = new List<ItemInfo>();
        }
        private class ItemInfo
        {
            public string itemName;
            public int minItemAmount;
            public int maxItemAmount;
            public float chance;
            public ulong skinID;
        }
        void SaveData()
        {
            storedData.lootTable = floatingCrateTable;
            floatingCrateFile.WriteObject(storedData);
            storedData.lootTable = icebergCrateTable;
            icebergCrateFile.WriteObject(storedData);
        }
        void LoadData()
        {
            try
            {
                bool dataChanged = false;
                floatingCrateFile = Interface.Oxide.DataFileSystem.GetFile("RustTanic/FloatingCrates");
                storedData = floatingCrateFile.ReadObject<StoredData>();
                floatingCrateTable = storedData.lootTable;
                if (floatingCrateTable.Count == 0)
                {
                    floatingCrateTable = new List<ItemInfo>
                    {
                        new ItemInfo {
                            itemName = "rope", minItemAmount = 2, maxItemAmount = 4, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "metalblade", minItemAmount = 1, maxItemAmount = 3, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "metalspring", minItemAmount = 1, maxItemAmount = 2, chance = 0.8f
                        },
                        new ItemInfo {
                            itemName = "scrap", minItemAmount = 10, maxItemAmount = 15, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "sheetmetal", minItemAmount = 1, maxItemAmount = 2, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "sewingkit", minItemAmount = 2, maxItemAmount = 4, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "propanetank", minItemAmount = 1, maxItemAmount = 1, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "pistol.revolver", minItemAmount = 1, maxItemAmount = 1, chance = 0.5f
                        },
                        new ItemInfo {
                            itemName = "gears", minItemAmount = 1, maxItemAmount = 3, chance = 0.8f
                        },
                        new ItemInfo {
                            itemName = "roadsigns", minItemAmount = 2, maxItemAmount = 5, chance = 1f
                        },
                    };
                    dataChanged = true;
                }
                icebergCrateFile = Interface.Oxide.DataFileSystem.GetFile("RustTanic/IcebergCrates");
                storedData = icebergCrateFile.ReadObject<StoredData>();
                icebergCrateTable = storedData.lootTable;
                if (icebergCrateTable.Count == 0)
                {
                    icebergCrateTable = new List<ItemInfo>
                    {
                        new ItemInfo {
                            itemName = "targeting.computer", minItemAmount = 1, maxItemAmount = 1, chance = 0.7f
                        },
                        new ItemInfo {
                            itemName = "techparts", minItemAmount = 1, maxItemAmount = 2, chance = 0.8f
                        },
                        new ItemInfo {
                            itemName = "scrap", minItemAmount = 20, maxItemAmount = 25, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "metal.refined", minItemAmount = 10, maxItemAmount = 20, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "metalpipe", minItemAmount = 1, maxItemAmount = 3, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "heavy.plate.helmet", minItemAmount = 1, maxItemAmount = 1, chance = 0.5f
                        },
                        new ItemInfo {
                            itemName = "heavy.plate.jacket", minItemAmount = 1, maxItemAmount = 1, chance = 0.5f
                        },
                        new ItemInfo {
                            itemName = "heavy.plate.pants", minItemAmount = 1, maxItemAmount = 1, chance = 0.5f
                        },
                        new ItemInfo {
                            itemName = "largemedkit", minItemAmount = 1, maxItemAmount = 3, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "shotgun.waterpipe", minItemAmount = 1, maxItemAmount = 1, chance = 0.8f
                        },
                        new ItemInfo {
                            itemName = "axe.salvaged", minItemAmount = 1, maxItemAmount = 1, chance = 0.8f
                        },
                        new ItemInfo {
                            itemName = "icepick.salvaged", minItemAmount = 1, maxItemAmount = 1, chance = 0.8f
                        },
                        new ItemInfo {
                            itemName = "smgbody", minItemAmount = 1, maxItemAmount = 2, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "semibody", minItemAmount = 1, maxItemAmount = 2, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "riflebody", minItemAmount = 1, maxItemAmount = 2, chance = 0.7f
                        },
                        new ItemInfo {
                            itemName = "pistol.semiauto", minItemAmount = 1, maxItemAmount = 1, chance = 0.7f
                        },
                        new ItemInfo {
                            itemName = "ammo.rifle", minItemAmount = 10, maxItemAmount = 25, chance = 1f
                        },
                        new ItemInfo {
                            itemName = "weapon.mod.holosight", minItemAmount = 1, maxItemAmount = 1, chance = 0.7f
                        },
                        new ItemInfo {
                            itemName = "rifle.bolt", minItemAmount = 1, maxItemAmount = 1, chance = 0.5f
                        },
                        new ItemInfo {
                            itemName = "rifle.semiauto", minItemAmount = 1, maxItemAmount = 1, chance = 0.7f
                        },
                        new ItemInfo {
                            itemName = "wall.external.high.stone", minItemAmount = 1, maxItemAmount = 3, chance = 0.9f
                        },
                    };
                    dataChanged = true;
                }
                if (dataChanged)
                {
                    Puts("Blank spawntables were found...Generating new ones");
                    SaveData();
                }
            }
            catch
            {
                Puts("Failed to load data, creating new file");
                storedData = new StoredData();
            }
        }
        private void OnServerInitialized()
        {
            plugin = this;
            LoadVariables();
            LoadData();
            permission.RegisterPermission(permissionNameADMIN, this);
            manager = new GameObject().AddComponent<TitanicManager>();
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["No Permission"] = "You are not allowed to use this command",
                ["ETA Message"] = "На горизонте появился корабль с пиратами! Они захватили ценный груз и хотят его припрятать на нашем острове!\nПоторопись забрать все самое ценное! Прибудет через ~ {0}s",
                ["Collide Message 1"] = "Пираты не справились с управлением и столкнулись с айсбергом! Поспеши, место крушения ты можешь посмотреть на карте, но будь аккуратней!",
                ["Collider Message 2"] = "Пираты не справились с управлением и столкнулись с айсбергом! Поспеши на место крушения, но будь аккуратней!",
            }, this);
        }
        private void Unload()
        {
            UnityEngine.Object.Destroy(manager.gameObject);
        }
        private class TitanicManager : FacepunchBehaviour
        {
            private List<GameObject> allIcebergs = new List<GameObject>();
            public List<GameObject> targetIcebergs = new List<GameObject>();
            public List<Titanic> currentTitanics = new List<Titanic>();
            private Dictionary<CargoShip, GameObject> setIcebergs = new Dictionary<CargoShip, GameObject>();
            private void Awake()
            {
                plugin.Puts("Finding all icebergs...");
                PopulateAllIcebergs();
                if (allIcebergs.Count == 0)
                {
                    plugin.PrintError("No icebergs were found on the map...This plugin is useless and will be disabled until a map with icebergs is found");
                    Interface.Oxide.UnloadPlugin(plugin.Name);
                }
                if (ConfigFile.randomEventEnabled) Invoke(TimedEvent, UnityEngine.Random.Range(ConfigFile.minRandomEventTime, ConfigFile.maxRandomEventTime));
                plugin.Puts("Marking all viable icebergs...");
                StartCoroutine(UpdateViableIcebergs());
                InvokeRepeating(() =>
                {
                    UpdateViableIcebergs();
                }, 300f, 300f);
            }
            private void OnDestroy()
            {
                foreach (Titanic ship in FindObjectsOfType<Titanic>())
                {
                    ship.GetComponent<BaseEntity>()?.Kill();
                }
            }
            private void PopulateAllIcebergs()
            {
                foreach (GameObject obj in FindObjectsOfType<GameObject>())
                {
                    if (obj.name.Contains("iceberg") && !obj.name.Contains("."))
                    {
                        allIcebergs.Add(obj);
                    }
                }
            }
            private IEnumerator UpdateViableIcebergs()
            {
                targetIcebergs.Clear();
                foreach (GameObject berg in allIcebergs)
                {
                    yield
                    return new WaitForSeconds(0.01f);
                    bool viable = true;
                    RaycastHit[] hits = UnityEngine.Physics.BoxCastAll(berg.transform.position, berg.GetComponent<Collider>().bounds.extents, Vector3.up);
                    foreach (RaycastHit hit in hits)
                    {
                        yield
                        return new WaitForSeconds(0.01f);
                        if (ConfigFile.disableIcebergsWithCupboard)
                        {
                            if (hit.collider?.GetComponent<BuildingPrivlidge>())
                            {
                                viable = false;
                                break;
                            }
                        }
                        if (ConfigFile.disableIcebergsWithBuilding)
                        {
                            if (hit.collider?.GetComponent<BuildingBlock>())
                            {
                                viable = false;
                                break;
                            }
                        }
                    }
                    if (viable == true) targetIcebergs.Add(berg);
                    if (ConfigFile.debugMode)
                    {
                        foreach (BasePlayer player in BasePlayer.activePlayerList)
                        {
                            yield
                            return new WaitForSeconds(0.01f);
                            if (player.IsAdmin)
                            {
                                if (viable == true) player.SendConsoleCommand("ddraw.text", 60f, Color.green, berg.transform.position + new Vector3(0, 50, 0), $"{berg.name} (Viable)");
                                else player.SendConsoleCommand("ddraw.text", 60f, Color.red, berg.transform.position + new Vector3(0, 50, 0), $"{berg.name} (Not Viable)");
                            }
                        }
                    }
                }
                plugin.Puts($"{targetIcebergs.Count} viable icebergs were found");
            }
            public void TimedEvent()
            {
                if (BasePlayer.activePlayerList.Count < ConfigFile.minPlayersForEvent) return;
                SpawnTitanic();
                Invoke(TimedEvent, UnityEngine.Random.Range(ConfigFile.minRandomEventTime, ConfigFile.maxRandomEventTime));
            }
            public void SpawnNearestIceberg(Vector3 pos)
            {
                GameObject nearest = null;
                float currentDistance = float.PositiveInfinity;
                foreach (GameObject obj in targetIcebergs)
                {
                    float dist = Vector3.Distance(obj.transform.position, pos);
                    if (dist < currentDistance)
                    {
                        nearest = obj;
                        currentDistance = dist;
                    }
                }
                SpawnTitanic(nearest);
            }
            public void SpawnTitanic(GameObject targetIceberg = null)
            {
                CargoShip ship = GameManager.server.CreateEntity("assets/content/vehicles/boats/cargoship/cargoshiptest.prefab", new Vector3(ConVar.Server.worldsize, 0f, ConVar.Server.worldsize),
                    default(Quaternion), true).GetComponent<CargoShip>();
                if (targetIceberg != null) setIcebergs.Add(ship, targetIceberg);
                ship.Spawn();
                ship.gameObject.AddComponent<Titanic>();
            }
            public GameObject GetTargetIceberg(CargoShip ship)
            {
                if (ship != null)
                {
                    GameObject targetBerg = null;
                    if (setIcebergs.TryGetValue(ship, out targetBerg))
                    {
                        setIcebergs.Remove(ship);
                        return targetBerg;
                    }
                }
                int random = UnityEngine.Random.Range(0, targetIcebergs.Count);
                if (random >= targetIcebergs.Count) random = targetIcebergs.Count - 1;
                if (random < 0) random = 0;
                return targetIcebergs[random];
            }
        }
        private class Titanic : FacepunchBehaviour
        {
            private CargoShip ship;
            public GameObject targetIceberg;
            private MapMarkerGenericRadius radiusMarker;
            private VendingMachineMapMarker textMarker;
            private Transform nosePosition;
            private Transform exhaust1;
            private Transform exhaust2;
            private Vector3 collisionPoint;
            private Vector3 startSinkingPosition;
            private Vector3 halfSinkingPosition;
            private Vector3 finishedSinkingPosition;
            private List<Vector3> deckExplosionPositions = new List<Vector3>
            {
                {
                    new Vector3(-1.9f, 9.5f, 75f)
                },
                {
                    new Vector3(3.6f, 9.5f, 67.4f)
                },
                {
                    new Vector3(-5.8f, 9.5f, 68.7f)
                },
                {
                    new Vector3(-1.2f, 10.8f, 59.7f)
                },
                {
                    new Vector3(7.4f, 9.5f, 58.3f)
                },
                {
                    new Vector3(-1.2f, 9.5f, 56.7f)
                },
                {
                    new Vector3(-7.4f, 9.5f, 58.5f)
                },
                {
                    new Vector3(-1.7f, 9.5f, 46.4f)
                },
                {
                    new Vector3(-9.3f, 6.5f, 49.7f)
                },
                {
                    new Vector3(7.0f, 6.5f, 50.4f)
                },
                {
                    new Vector3(2.1f, 9.5f, 32.7f)
                },
                {
                    new Vector3(-9.9f, 6.5f, 24.8f)
                },
                {
                    new Vector3(-1.7f, 9.5f, 24.4f)
                },
                {
                    new Vector3(5.8f, 6.5f, 22.8f)
                },
                {
                    new Vector3(-0.9f, 9.5f, 16.5f)
                },
                {
                    new Vector3(-0.4f, 9.5f, 4.8f)
                },
                {
                    new Vector3(6.1f, 6.5f, -1.7f)
                },
                {
                    new Vector3(-8.6f, 6.5f, -3.0f)
                },
                {
                    new Vector3(-2.6f, 9.5f, -9.6f)
                },
                {
                    new Vector3(-2.9f, 9.5f, -20.9f)
                },
                {
                    new Vector3(-1.6f, 9.5f, -27.2f)
                },
                {
                    new Vector3(-8.6f, 6.5f, -28.4f)
                },
                {
                    new Vector3(5.6f, 6.5f, -28.3f)
                },
                {
                    new Vector3(4.4f, 9.5f, -34.9f)
                },
                {
                    new Vector3(-6.9f, 9.5f, -34.7f)
                },
                {
                    new Vector3(5.5f, 9.5f, -55.3f)
                },
                {
                    new Vector3(-10.3f, 9.8f, -54.5f)
                },
                {
                    new Vector3(-9.0f, 12.1f, -49.6f)
                },
                {
                    new Vector3(6.2f, 12.5f, -49.6f)
                },
                {
                    new Vector3(8.7f, 24.5f, -45.5f)
                },
                {
                    new Vector3(-12.0f, 25.6f, -45.2f)
                },
                {
                    new Vector3(-7.5f, 27.5f, -42.8f)
                },
                {
                    new Vector3(3.8f, 27.5f, -44.2f)
                },
                {
                    new Vector3(-1.2f, 31.2f, -45.4f)
                },
                {
                    new Vector3(-1.5f, 36.5f, -45.6f)
                },
            };
            private List<Vector3> searchLightPositions = new List<Vector3>
            {
                {
                    new Vector3(0f, 17.5f, 69.6f)
                },
                {
                    new Vector3(-9.8f, 27.5f, -40.5f)
                },
                {
                    new Vector3(9.8f, 27.5f, -40.5f)
                },
                {
                    new Vector3(-10.7f, 12.5f, -38.8f)
                },
                {
                    new Vector3(10.7f, 12.5f, -38.8f)
                },
            };
            private List<BaseEntity> searchLights = new List<BaseEntity>();
            private List<BaseEntity> npcs = new List<BaseEntity>();
            private List<Transform> shipTransforms = new List<Transform>();
            private Coroutine exhaustFireRoutine;
            private float tippingSpeed = 0f;
            public bool hasCollided;
            public bool isTipping = false;
            public bool isSinking = false;
            public bool isReverseTipping = false;
            public bool isFinalSinking = false;
            public bool isPaused = false;
            private float finalSinkStartTime;
            private float pauseEndTime;
            private float startTime;
            private float startDistance;
            private void Awake()
            {
                ship = GetComponent<CargoShip>();
                targetIceberg = plugin.manager.GetTargetIceberg(ship);
                InitializeSpawnPosition();
                ship.enabled = false;
                InitializeTransform(ref nosePosition, new Vector3(0f, 0.5f, 74.1f));
                InitializeTransform(ref exhaust1, new Vector3(-2.5f, 32.4f, -53.8f));
                InitializeTransform(ref exhaust2, new Vector3(-2.2f, 33f, -52.4f));
                transform.LookAt(new Vector3(collisionPoint.x, transform.position.y, collisionPoint.z));
                Invoke(SetCollisionPoint, 0.5f);
                CancelInvoke(new Action(ship.RespawnLoot));
                StartCoroutine(SetHackableCrateTimers());
                if (ship.crateSpawns == null || ship.crateSpawns.Count == 0) plugin.PrintError("A CargoShips crateSpawns was null.If you are seeing this error, please report it to redBDGR via the plugin support thread");
                SetInitExtraEffects();
                startDistance = Vector3.Distance(targetIceberg.transform.position, transform.position);
                startTime = UnityEngine.Time.time;
                if (targetIceberg == null)
                {
                    plugin.PrintError("Event CargoShip couldn't find a target iceberg.It has been despawned");
                    ship.Kill();
                    return;
                }
                Broadcast(string.Format(plugin.msg("ETA Message"), Mathf.Round(Vector3.Distance(targetIceberg.transform.position, transform.position) / 6.7f)));
                if (ConfigFile.targetIcebergMarkerEnabled)
                {
                    radiusMarker = GameManager.server.CreateEntity("assets/prefabs/tools/map/genericradiusmarker.prefab", targetIceberg.transform.position,
                        default(Quaternion), true).GetComponent<MapMarkerGenericRadius>();
                    radiusMarker.radius = ConfigFile.targetIcebergMarkerRadius;
                    radiusMarker.color1 = Color.red;
                    radiusMarker.alpha = 0.4f;
                    radiusMarker.Spawn();
                    radiusMarker.SendUpdate();
                    textMarker = GameManager.server.CreateEntity("assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab", targetIceberg.transform.position,
                        default(Quaternion), true).GetComponent<VendingMachineMapMarker>();
                    textMarker.markerShopName = ConfigFile.targetIcerbergText;
                    textMarker.Spawn();
                }
            }
            private void OnDestroy()
            {
                Destroy(nosePosition.gameObject);
                foreach (BaseEntity light in searchLights) light.Kill();
                if (radiusMarker) radiusMarker.Kill();
                if (textMarker) textMarker.Kill();
                foreach (BaseEntity ent in npcs) ent.Kill();
            }
            private void FixedUpdate()
            {
                if (hasCollided == false)
                {
                    transform.position = Vector3.MoveTowards(transform.position, new Vector3(collisionPoint.x, transform.position.y, collisionPoint.z), 0.2f * ConfigFile.boatSpeed);
                    if (Vector3.Distance(nosePosition.position, new Vector3(collisionPoint.x, nosePosition.position.y, collisionPoint.z)) < 1f) OnCollideWithIceberg();
                    return;
                }
                if (isPaused)
                {
                    if (UnityEngine.Time.time >= pauseEndTime) isPaused = false;
                    else return;
                }
                if (isTipping == true)
                {
                    if (exhaust1.position.y < ship.waterLine.position.y)
                    {
                        StopCoroutine(exhaustFireRoutine);
                    }
                    if (transform.rotation.eulerAngles.z < 20f)
                    {
                        transform.Rotate(Quaternion.Euler(0f, 0f, tippingSpeed).eulerAngles);
                        if (tippingSpeed < 0.1f) tippingSpeed += 0.0001f;
                    }
                    if (transform.rotation.eulerAngles.x < 5f)
                    {
                        transform.Rotate(Quaternion.Euler(0f, tippingSpeed, 0f).eulerAngles);
                    }
                    if (transform.rotation.eulerAngles.z >= 20f && transform.rotation.eulerAngles.y >= 5f) OnFinishTipping();
                }
                if (isSinking)
                {
                    transform.position = Vector3.MoveTowards(transform.position, halfSinkingPosition, UnityEngine.Time.deltaTime * 0.1f);
                    if (Vector3.Distance(transform.position, halfSinkingPosition) < 0.1f) OnFinishSinking();
                }
                if (isReverseTipping)
                {
                    if (transform.rotation.eulerAngles.z > 0f)
                    {
                        transform.Rotate(Quaternion.Euler(0f, 0f, -tippingSpeed).eulerAngles);
                        if (tippingSpeed < 0.1f) tippingSpeed += 0.0001f;
                    }
                    if (transform.rotation.eulerAngles.z <= 1f) OnFinishReverseTipping();
                }
                if (isFinalSinking)
                {
                    if (UnityEngine.Time.time < finalSinkStartTime) { }
                    transform.position = Vector3.MoveTowards(transform.position, finishedSinkingPosition, UnityEngine.Time.deltaTime * 0.5f);
                    if (Vector3.Distance(transform.position, finishedSinkingPosition) < 0.5f) StartCoroutine(FinalExplosion());
                }
            }
            private void SetInitExtraEffects()
            {
                InvokeRepeating(() => ship.ClientRPC(null, "DoHornSound"), ConfigFile.boatHornInterval, ConfigFile.boatHornInterval);
                if (ConfigFile.boatExhaustFlames) exhaustFireRoutine = StartCoroutine(FireFromExhaust());
                if (ConfigFile.boatRotatingLights) InitSearchLights();
            }
            private void InitSearchLights()
            {
                foreach (Vector3 pos in searchLightPositions)
                {
                    BaseEntity ent = GameManager.server.CreateEntity("assets/prefabs/deployable/search light/searchlight.deployed.prefab", ship.transform.TransformPoint(pos), new Quaternion(), true);
                    ent.Spawn();
                    ent.SetParent(ship);
                    ent.transform.localPosition = pos;
                    ent.gameObject.AddComponent<TitanicSpinningLight>();
                    searchLights.Add(ent);
                }
            }
            private IEnumerator FireFromExhaust()
            {
                while (true)
                {
                    yield
                    return new WaitForSeconds(UnityEngine.Random.Range(0.3f, 0.6f));
                    BaseEntity ent = GameManager.server.CreateEntity("assets/bundled/prefabs/napalm.prefab", exhaust1.position, new Quaternion(), true);
                    ent.Spawn();
                    ent.GetComponent<Rigidbody>().AddForce(UnityEngine.Random.Range(-4, 4), UnityEngine.Random.Range(3, 6), UnityEngine.Random.Range(-4, 4), ForceMode.Impulse);
                    ent.Invoke(() =>
                    {
                        if (ent) ent.Kill();
                    }, 5f);
                }
            }
            private IEnumerator ExplodeDeck()
            {
                foreach (Vector3 pos in deckExplosionPositions)
                {
                    if (pos == null) continue;
                    yield
                    return new WaitForSeconds(0.01f);
                    Vector3 _pos = transform.TransformPoint(pos);
                    Effect.server.Run("assets/prefabs/tools/c4/effects/c4_explosion.prefab", _pos);
                    if (ConfigFile.disableExtraEffects == false)
                    {
                        for (int i = 0; i <= 3; i++)
                        {
                            yield
                            return new WaitForSeconds(0.01f);
                            string type = UnityEngine.Random.Range(0f, 1f) > 0.5f ? "assets/bundled/prefabs/napalm.prefab" : "assets/bundled/prefabs/oilfireballsmall.prefab";
                            BaseEntity ent = GameManager.server.CreateEntity(type, _pos, new Quaternion(), true);
                            ent.Spawn();
                            ent.GetComponent<Rigidbody>().AddForce(UnityEngine.Random.Range(-4, 4), UnityEngine.Random.Range(3, 6), UnityEngine.Random.Range(-4, 4), ForceMode.Impulse);
                            ent.Invoke(() =>
                            {
                                if (ent) ent.Kill();
                            }, 7f);
                        }
                        BaseEntity ent2 = GameManager.server.CreateEntity("assets/bundled/prefabs/oilfireballsmall.prefab", _pos, new Quaternion(), true);
                        ent2.Spawn();
                    }
                }
            }
            private void SetCollisionPoint()
            {
                RaycastHit[] hits = UnityEngine.Physics.RaycastAll(nosePosition.position, transform.forward, Vector3.Distance(transform.position, targetIceberg.transform.position), plugin.worldLayer);
                foreach (RaycastHit hit in hits)
                {
                    Collider col = hit.GetCollider();
                    if (!col) continue;
                    if (col.gameObject == targetIceberg) collisionPoint = new Vector3(hit.point.x, nosePosition.position.y, hit.point.z);
                }
                if (collisionPoint == null || Vector3.Distance(collisionPoint, targetIceberg.transform.position) > 30f)
                    if (collisionPoint == null || collisionPoint == Vector3.zero) collisionPoint = targetIceberg.GetComponent<Collider>().ClosestPointOnBounds(nosePosition.position);
            }
            private void OnCollideWithIceberg()
            {
                hasCollided = true;
                isTipping = true;
                isSinking = true;
                startSinkingPosition = transform.position;
                halfSinkingPosition = startSinkingPosition - new Vector3(0f, 20f, 0f);
                PauseToLoot(ConfigFile.sequencingGaps);
                if (ConfigFile.targetIcebergMarkerEnabled) Broadcast(plugin.msg("Collide Message 1"));
                else Broadcast(plugin.msg("Collide Message 2"));
                ship.CancelInvoke("DelayedDestroy");
                ship.scientistSpawnPoints = new Transform[0];
                StartCoroutine(ExplodeDeck());
                HandleLoot();
                StartCoroutine(HandleNPCs());
                ship.StartEgress();
                ship.CancelInvoke("UpdateRadiation");
                ship.radiation.SetActive(false);
            }
            private void OnFinishTipping()
            {
                isTipping = false;
                if (isTipping == false && isSinking == false)
                {
                    StartTipCorrection();
                }
            }
            private void OnFinishSinking()
            {
                isSinking = false;
                if (isTipping == false && isSinking == false)
                {
                    StartTipCorrection();
                }
            }
            private void StartTipCorrection()
            {
                tippingSpeed = 0f;
                isReverseTipping = true;
                finalSinkStartTime = UnityEngine.Time.time + 120f;
                StopCoroutine(exhaustFireRoutine);
            }
            private void OnFinishReverseTipping()
            {
                PauseToLoot(ConfigFile.sequencingGaps);
                isReverseTipping = false;
                isFinalSinking = true;
                CancelInvoke(() => ship.ClientRPC(null, "DoHornSound"));
                ship.CancelInvoke(ship.PlayHorn);
                RaycastHit hit;
                if (UnityEngine.Physics.Raycast(transform.position, Vector3.down, out hit, float.PositiveInfinity, 1274232599)) finishedSinkingPosition = hit.point;
                else finishedSinkingPosition = transform.position - new Vector3(0, 30f, 0);
            }
            private IEnumerator FinalExplosion()
            {
                isFinalSinking = false;
                yield
                return new WaitForSeconds(ConfigFile.sequencingGaps);
                yield
                return StartCoroutine(ExplodeDeck());
                for (int i = 0; i < ConfigFile.debisToSpawn; i++)
                {
                    yield
                    return new WaitForSeconds(0.01f);
                    Vector3 spawnPos = transform.position + (UnityEngine.Random.insideUnitSphere * 10f);
                    spawnPos.y = TerrainMeta.HeightMap.GetHeight(spawnPos) + 2f;
                    BaseCombatEntity ent = GameManager.server.CreateEntity("assets/prefabs/npc/m2bradley/bradleyapc.prefab", spawnPos, UnityEngine.Random.rotation, true).GetComponent<BaseCombatEntity>();
                    ent.Spawn();
                    ent.GetComponent<BradleyAPC>().maxCratesToSpawn = ConfigFile.lootPerDebris;
                    ent.Hurt(9999999f, DamageType.Explosion);
                }
                foreach (RaycastHit entry in UnityEngine.Physics.SphereCastAll(transform.position, 10f, Vector3.up, 10f, plugin.defaultLayer))
                {
                    yield
                    return new WaitForSeconds(0.01f);
                    BaseEntity ent = entry.GetEntity();
                    if (!ent) continue;
                    HelicopterDebris debris = ent.GetComponent<HelicopterDebris>();
                    if (debris == null) continue;
                    plugin.tooHotUntil.SetValue(debris, 0f);
                }
                if (ship) ship.Kill();
            }
            private IEnumerator HandleNPCs()
            {
                if (ConfigFile.killBoatScientists) foreach (HTNPlayer entry in ship.GetComponentsInChildren<HTNPlayer>())
                    {
                        yield
                        return new WaitForSeconds(0.01f);
                        entry.SetParent(null);
                        entry.Hurt(entry.health);
                    }
                for (int i = 0; i < ConfigFile.icebergNPCToSpawn; i++)
                {
                    yield
                    return new WaitForSeconds(0.01f);
                    RaycastHit hit;
                    if (UnityEngine.Physics.Raycast(targetIceberg.transform.position + (UnityEngine.Random.insideUnitSphere * ConfigFile.icebergNPCSpawnRadius) + new Vector3(0, 50f, 0), Vector3.down, out hit, float.PositiveInfinity, 1274232599))
                    {
                        Vector3 spawnPos = hit.point;
                        BaseEntity ent = GameManager.server.CreateEntity(ConfigFile.icebergNPCType, spawnPos,
                            default(Quaternion), true);
                        ent.Spawn();
                        npcs.Add(ent);
                        ent.SetParent(null);
                        BasePlayer _npcPlayer = ent.GetComponent<BasePlayer>();
                        if (_npcPlayer) _npcPlayer.displayName = ConfigFile.icebergNPCNames;
                    }
                }
            }
            private void HandleLoot()
            {
                ship.RespawnLoot();
                StartCoroutine(SetHackableCrateTimers());
                StartCoroutine(SpawnIcebergCrates());
                StartCoroutine(SpawnFloatingCrates());
                ship.CancelInvoke(new Action(ship.PlayHorn));
            }
            private IEnumerator SpawnIcebergCrates()
            {
                for (int i = 0; i < ConfigFile.icebergCratesToSpawn; i++)
                {
                    yield
                    return new WaitForSeconds(0.01f);
                    RaycastHit hit;
                    if (UnityEngine.Physics.Raycast(targetIceberg.transform.position + (UnityEngine.Random.insideUnitSphere * ConfigFile.icebergCratesSpawnRadius) + new Vector3(0, 50f, 0), Vector3.down, out hit, float.PositiveInfinity, 1274232599))
                    {
                        if (hit.GetEntity())
                        {
                            i--;
                            continue;
                        }
                        BaseEntity ent = GameManager.server.CreateEntity(ConfigFile.icebergCratePrefab, hit.point, Quaternion.Euler(0f, UnityEngine.Random.Range(0f, 360f), 0));
                        if (ent) ent.Spawn();
                        StartCoroutine(SpawnItems(ent.GetComponent<StorageContainer>().inventory, plugin.icebergCrateTable, ConfigFile.icebergCrateMinItems, ConfigFile.icebergCrateMaxItems));
                        ent.Invoke(() =>
                        {
                            if (ent) ent.Kill();
                        }, 600f);
                    }
                }
            }
            private IEnumerator SpawnFloatingCrates()
            {
                for (int i = 0; i < ConfigFile.floatingCratesToSpawn; i++)
                {
                    yield
                    return new WaitForSeconds(0.1f);
                    Vector3 randomPos = GetRandomOceanRadiusPosition(transform.position, ConfigFile.floatingCratesRadius);
                    Vector3 spawnPos = new Vector3(randomPos.x, randomPos.y - 30f, randomPos.z);
                    BaseEntity ent = GameManager.server.CreateEntity("assets/bundled/prefabs/radtown/crate_underwater_advanced.prefab", spawnPos, UnityEngine.Random.rotation, true);
                    ent.Spawn();
                    StartCoroutine(SpawnItems(ent.GetComponent<StorageContainer>().inventory, plugin.floatingCrateTable, ConfigFile.floatingCrateMinItems, ConfigFile.floatingCrateMaxItems));
                    FreeableLootContainer freeable = ent.GetComponent<FreeableLootContainer>();
                    freeable.GetRB().isKinematic = false;
                    freeable.buoyancy.enabled = true;
                    freeable.buoyancy.buoyancyScale = 1f;
                    freeable.SetFlag(BaseEntity.Flags.Reserved8, false, false);
                    freeable.Invoke(() =>
                    {
                        if (freeable) freeable.Kill();
                    }, ConfigFile.floatingCrateDespawnTime);
                }
            }
            private IEnumerator SpawnItems(ItemContainer container, List<ItemInfo> table, int min, int max)
            {
                container.Clear();
                int itemsCreated = 0;
                int targetAmount = UnityEngine.Random.Range(min, max);
                while (itemsCreated < targetAmount)
                {
                    yield
                    return new WaitForSeconds(0.01f);
                    ItemInfo data = table[UnityEngine.Random.Range(0, table.Count - 1)];
                    if (UnityEngine.Random.Range(0, 1) > data.chance)
                  
// ... [Code preview truncated due to length. Full source in attached file] ...

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