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

FREE Biplane : 1.0.9 1.0.9

Нет прав для скачивания
C#:
using Oxide.Plugins.BiplaneExtensionMethods;
using System.Collections.Generic;
using Oxide.Game.Rust.Cui;
using System.Collections;
using System.Reflection;
using Newtonsoft.Json;
using Rust.Modular;
using UnityEngine;
using Oxide.Core;
using Oxide.Core.Plugins;
using System;
namespace Oxide.Plugins {
    [Info("Biplane", "Adem", "1.0.9")]
    class Biplane : RustPlugin {
#region Variables
        const bool en = true;
        bool unload = false;
        private static Biplane ins;
        HashSet<BiplaneComponent> biplanes = new HashSet<BiplaneComponent>();
        List<SellerData> sellers = new List<SellerData>();
        HashSet<MonumentInfo> monuments = new HashSet<MonumentInfo>();
        Coroutine spawnCorountine;
        Coroutine saveCoroutine;
#endregion Variables
#region Hooks
        void OnServerInitialized() {
            ins = this;
            UpdateConfig();
            foreach (BiplaneSetting biplaneSetting in _config.biplanePresets.Values) {
                if (biplaneSetting.permission != "") permission.RegisterPermission(biplaneSetting.permission, this);
            }
            if (!_config.samSite && !_config.samSiteMonuments) Unsubscribe("OnSamSiteTargetScan");
            LoadDefaultMessages();
            permission.RegisterPermission(_config.itemPermission, this);
            foreach (MonumentInfo monumentInfo in TerrainMeta.Path.Monuments.Where(x => _config.spawnSetting.monumentSpawnSettings.ContainsKey(x.name))) monuments.Add(monumentInfo);
            if (_config.spawnSetting.monumentSpawnSettings.Any(x => x.Value.enableSpawn) || _config.spawnSetting.customSpawnPointsConfig.enableSpawn) spawnCorountine = ServerMgr.Instance.StartCoroutine(SpawnCorountine());
            SpawnSellersAtMonuments();
            LoadData();
            foreach (ModularCar modularCar in ModularCar.allCarsList) {
                if (!modularCar.IsExists() || modularCar.NumAttachedModules > 1) continue;
                SaveBiplaneData saveBiplaneData = saveBiplanes.FirstOrDefault(x => x.biplaneId == modularCar.net.ID.Value);
                if (saveBiplaneData == null) continue;
                BaseVehicleModule baseVehicleModule;
                modularCar.TryGetModuleAt(0, out baseVehicleModule);
                if (modularCar.NumAttachedModules == 0 || (modularCar.NumAttachedModules == 1 && baseVehicleModule != null && baseVehicleModule.name == "assets/content/vehicles/modularcar/module_entities/1module_engine.prefab")) LoadBiplane(modularCar, saveBiplaneData);
            }
            timer.In(1f, () => saveCoroutine = ServerMgr.Instance.StartCoroutine(SaveCorountine()));
        }
        void Unload() {
            if (saveCoroutine != null) ServerMgr.Instance.StopCoroutine(saveCoroutine);
            unload = true;
            if (spawnCorountine != null) ServerMgr.Instance.StopCoroutine(spawnCorountine);
            foreach (SellerData sellerData in sellers) sellerData.Destroy();
            foreach (BasePlayer player in BasePlayer.activePlayerList) {
                CuiHelper.DestroyUi(player, "BiplaneSellerPanel");
                CuiHelper.DestroyUi(player, "FuelText");
            }
            saveBiplanes.Clear();
            foreach (BiplaneComponent biplane in biplanes) {
                SaveBiplane(biplane);
                UnityEngine.Object.DestroyImmediate(biplane, true);
            }
            SaveData();
            ins = null;
        }
        object OnEntityTakeDamage(DecorWing entity, HitInfo info) {
            if (entity == null || info == null) return null;
            if (entity.ShortPrefabName.Contains("kayak") || entity.ShortPrefabName.Contains("boogieboard")) {
                BiplaneComponent biplaneComponent = biplanes.FirstOrDefault(x => x.subEntities.Contains(entity));
                if (biplaneComponent == null) return null;
                biplaneComponent.modularCar.Hurt(info);
                return true;
            }
            return null;
        }
        object CanMountEntity(BasePlayer player, BaseMountable entity) {
            if (player == null || entity == null || !player.userID.IsSteamId()) return null;
            BiplaneComponent biplaneComponent = biplanes.FirstOrDefault(x => x != null && (x.fakeSeat != null && x.fakeSeat == entity) || (x.pilotSeat != null && x.pilotSeat == entity));
            if (biplaneComponent != null) {
                if (biplaneComponent.biplaneSetting.permission != "" && !permission.UserHasPermission(player.UserIDString, biplaneComponent.biplaneSetting.permission)) {
                    PrintToChat(player, GetMessage("NoPermission", player.UserIDString, ins._config.prefics));
                    return true;
                }
                else if (biplaneComponent.modularCar.CarLock != null && !biplaneComponent.modularCar.CarLock.PlayerCanUseThis(player, ModularCarCodeLock.LockType.Door)) {
                    PrintToChat(player, GetMessage("Lock", player.UserIDString, ins._config.prefics));
                    return true;
                }
                else if (biplaneComponent.fakeSeat == entity) {
                    biplaneComponent.MountPlayer(player);
                    return true;
                }
            }
            return null;
        }
        void OnEntityBuilt(Planner plan, GameObject go) {
            if (plan == null || go == null) return;
            Item item = plan.GetItem();
            if (item == null) return;
            var pair = _config.itemsPresets.FirstOrDefault(x => x.Value.shortname == item.info.shortname && x.Value.skin == item.skin);
            if (pair.Value == null || pair.Key == null) return;
            BaseEntity entity = go.GetComponent<BaseEntity>();
            if (entity == null) return;
            CreateBiplane(entity.transform.position, entity.transform.rotation, _config.biplanePresets.FirstOrDefault(x => x.Value.customItemShortname == pair.Key).Key, true, false);
            NextTick(() => entity.Kill());
        }
        object OnNpcConversationStart(VehicleVendor vehicleVendor, BasePlayer player, ConversationData conversationData) {
            if (vehicleVendor != null) {
                SellerData sellerData = sellers.FirstOrDefault(x => x.seller == vehicleVendor);
                if (sellerData != null) {
                    CreateGui(player, sellerData.sellerPrefab, sellers.IndexOf(sellerData));
                    return true;
                }
            }
            return null;
        }
        void OnEntityMounted(BaseMountable entity, BasePlayer player) {
            if (entity == null) return;
            BiplaneComponent biplaneComponent = biplanes.FirstOrDefault(x => x != null && x.pilotSeat != null && x.pilotSeat.net.ID == entity.net.ID);
            if (biplaneComponent != null) biplaneComponent.UnSleep();
        }
        void OnEntityDismounted(BaseMountable entity, BasePlayer player) {
            if (entity == null) return;
            BiplaneComponent biplaneComponent = biplanes.FirstOrDefault(x => x != null && x.pilotSeat != null && x.pilotSeat == entity);
            if (biplaneComponent != null) CuiHelper.DestroyUi(player, "FuelText");
        }
        object OnEngineStart(BaseVehicle vehicle, BasePlayer driver) {
            if (vehicle == null || driver == null) return null;
            BiplaneComponent biplaneComponent = biplanes.FirstOrDefault(x => x.modularCar.net.ID == vehicle.net.ID);
            if (biplaneComponent == null) return null;
            if (biplaneComponent.modularCar.CarLock != null && !biplaneComponent.modularCar.CarLock.PlayerCanUseThis(driver, ModularCarCodeLock.LockType.Door)) {
                PrintToChat(driver, GetMessage("Lock", driver.UserIDString, ins._config.prefics));
                return true;
            }
            return null;
        }
        object CanLootEntity(BasePlayer player, StorageContainer container) {
            if (player == null || container == null) return null;
            BiplaneComponent biplaneComponent = null;
            if (container.ShortPrefabName == "rhib_storage") biplaneComponent = biplanes.FirstOrDefault(x => x.container.net.ID == container.net.ID);
            else if (container.ShortPrefabName == "modular_car_v8_engine_storage" || container.ShortPrefabName == "modular_car_fuel_storage") biplaneComponent = container.GetComponentInParent<BiplaneComponent>();
            if (biplaneComponent == null) return null;
            if (biplaneComponent.biplaneSetting.permission != "" && !permission.UserHasPermission(player.UserIDString, biplaneComponent.biplaneSetting.permission)) {
                PrintToChat(player, GetMessage("NoPermission", player.UserIDString, ins._config.prefics));
                return true;
            }
            if (biplaneComponent.modularCar.CarLock != null && !biplaneComponent.modularCar.CarLock.PlayerCanUseThis(player, ModularCarCodeLock.LockType.Door)) {
                PrintToChat(player, GetMessage("Lock", player.UserIDString, ins._config.prefics));
                return true;
            }
            return null;
        }
        object CanPickupEntity(BasePlayer player, BaseEntity entity) {
            if (entity.PrefabName.Contains("kayak") && entity is Kayak == false) {
                BiplaneComponent biplaneComponent = entity.GetComponentInParent<BiplaneComponent>();
                if (biplaneComponent == null) return null;
                if (biplaneComponent.biplaneSetting.customItemShortname != "") {
                    if (!ins._config.allowIpckUp) return false;
                    if (biplaneComponent.biplaneSetting.permission != "" && !permission.UserHasPermission(player.UserIDString, biplaneComponent.biplaneSetting.permission)) {
                        PrintToChat(player, GetMessage("NoPermission", player.UserIDString, ins._config.prefics));
                        return false;
                    }
                    if (biplaneComponent.modularCar.CarLock != null && !biplaneComponent.modularCar.CarLock.PlayerCanUseThis(player, ModularCarCodeLock.LockType.Door)) {
                        PrintToChat(player, GetMessage("Lock", player.UserIDString, ins._config.prefics));
                        return false;
                    }
                    else if (biplaneComponent.modularCar.GetFuelSystem().GetFuelAmount() > 0 || biplaneComponent.container.inventory.itemList.Count > 0) {
                        PrintToChat(player, GetMessage("EmptyСontainers", player.UserIDString, ins._config.prefics));
                        return false;
                    }
                    foreach (BaseVehicleModule module in biplaneComponent.modularCar.AttachedModuleEntities) {
                        VehicleModuleEngine engineModule = module as VehicleModuleEngine;
                        if (engineModule == null) continue;
                        Rust.Modular.EngineStorage engineStorage = engineModule.GetContainer() as Rust.Modular.EngineStorage;
                        if (engineStorage == null) continue;
                        if (engineStorage.inventory.itemList.Count > 0) {
                            PrintToChat(player, GetMessage("EmptyСontainers", player.UserIDString, ins._config.prefics));
                            return false;
                        }
                    }
                    MoveItem(player, CreateItem(_config.itemsPresets[biplaneComponent.biplaneSetting.customItemShortname]));
                    biplaneComponent.modularCar.Kill();
                }
                return false;
            }
            return null;
        }
        void OnLicensedVehicleSpawned(BaseEntity entity, BasePlayer player, string vehicleType) {
            if (vehicleType != null && _config.biplanePresets.ContainsKey(vehicleType) && entity != null && entity.ShortPrefabName.Contains("3module.entity")) {
                BiplaneComponent biplaneComponent = entity.gameObject.AddComponent<BiplaneComponent>();
                biplaneComponent.Init(vehicleType, false);
                biplanes.Add(biplaneComponent);
            }
        }
#endregion Hooks
#region Commands
        [ChatCommand("biplanemonument")]
        private void ChatNewBiplaneMonument(BasePlayer player) {
            if (!player.IsAdmin) return;
            MonumentInfo monumentInfo = TerrainMeta.Path.Monuments.FirstOrDefault(x => Vector3.Distance(player.transform.position, x.transform.position) < x.Bounds.size.x);
            if (monumentInfo == null) {
                PrintToChat(player, "Monument not found!");
                return;
            }
            if (_config.spawnSetting.monumentSpawnSettings.ContainsKey(monumentInfo.name)) {
                PrintToChat(player, "The monument has already been added");
                return;
            }
            _config.spawnSetting.monumentSpawnSettings.Add(monumentInfo.name, new MonumentConfig());
            SaveConfig();
        }
        [ChatCommand("biplanemonumentpoint")]
        private void ChatNewBiplanePoint(BasePlayer player) {
            if (!player.IsAdmin) return;
            MonumentConfig monumentConfig;
            LocationConfig locationConfig;
            DefineMonumentAndPlayerLocation(player, out monumentConfig, out locationConfig);
            if (monumentConfig == null || locationConfig == null) return;
            monumentConfig.points.Add(locationConfig);
            PrintToChat(player, "The biplane spawn point has been successfully added to the location");
            SaveConfig();
        }
        [ChatCommand("biplaneseller")]
        private void ChatNewBiplaneSeller(BasePlayer player) {
            if (!player.IsAdmin) return;
            MonumentConfig monumentConfig;
            LocationConfig locationConfig;
            DefineMonumentAndPlayerLocation(player, out monumentConfig, out locationConfig);
            if (monumentConfig == null || locationConfig == null) return;
            monumentConfig.sellerLocation = locationConfig;
            PrintToChat(player, "The seller's spawn point has been successfully added to the location");
            SaveConfig();
        }
        [ChatCommand("biplanesellerpoint")]
        private void ChatNewBiplaneSellerPoint(BasePlayer player) {
            if (!player.IsAdmin) return;
            MonumentConfig monumentConfig;
            LocationConfig locationConfig;
            DefineMonumentAndPlayerLocation(player, out monumentConfig, out locationConfig);
            if (monumentConfig == null || locationConfig == null) return;
            monumentConfig.sellerBiplaneLocation = locationConfig;
            PrintToChat(player, "The seller's biplane spawn point has been successfully added to the location");
            SaveConfig();
        }
        [ChatCommand("givebiplane")]
        void BiplaneGiveCommandk(BasePlayer player, string command, string[] arg) {
            if (player == null || arg == null || arg.Length == 0) return;
            if (!_config.itemsPresets.ContainsKey(arg[0])) return;
            if (!permission.UserHasPermission(player.UserIDString, _config.itemPermission)) {
                PrintToChat(player, "You do not have permission to use this command!");
                return;
            }
            MoveItem(player, CreateItem(_config.itemsPresets[arg[0]]));
            PrintToChat(player, GetMessage("GetBiplane", player.UserIDString, ins._config.prefics));
        }
        [ConsoleCommand("givebiplane")]
        void GiveCustomItemCommand(ConsoleSystem.Arg arg) {
            BasePlayer player = arg.Player();
            BasePlayer target = null;
            bool rcon = player == null;
            if (arg.Args == null || arg.Args.Length == 0) return;
            if (player != null) {
                if (!permission.UserHasPermission(player.UserIDString, _config.itemPermission) && !rcon) {
                    PrintToConsole(player, "You do not have permission to use this command!");
                    return;
                }
                if (arg.Args.Length == 1 && !rcon) target = player;
                else target = BasePlayer.FindByID(Convert.ToUInt64(arg.Args[1]));
            }
            else if (arg.Args.Length >= 2) target = BasePlayer.FindByID(Convert.ToUInt64(arg.Args[1]));
            if (target == null) {
                if (rcon) Puts("Player not found");
                else PrintToConsole(player, "Player not found");
                return;
            }
            MoveItem(target, CreateItem(_config.itemsPresets[arg.Args[0]]));
            PrintToChat(target, GetMessage("GetBiplane", target.UserIDString, ins._config.prefics));
            if (rcon) Puts($"A biplane was given to {target.displayName}");
            else PrintToConsole(player, $"A biplane was given to {target.displayName}");
        }
        [ChatCommand("biplanecustomspawnpoint")]
        private void ChatNewCustomSpawnPoint(BasePlayer player) {
            if (!player.IsAdmin) return;
            _config.spawnSetting.customSpawnPointsConfig.points.Add(new LocationConfig {
                position = player.transform.position.ToString(), rotation = player.viewAngles.y.ToString()
            }
            );
            PrintToChat(player, "Custom spawn point successfully added");
            SaveConfig();
        }
#endregion Commands
#region Methods
        void UpdateConfig() {
            if (_config.version != Version.ToString()) {
                VersionNumber versionNumber;
                var versionArray = _config.version.Split('.');
                versionNumber.Major = Convert.ToInt32(versionArray[0]);
                versionNumber.Minor = Convert.ToInt32(versionArray[1]);
                versionNumber.Patch = Convert.ToInt32(versionArray[2]);
                if (versionNumber.Patch == 0) {
                    PrintError("Delete the configuration file!");
                    NextTick(() => Server.Command($"o.unload {Name}"));
                    return;
                }
                if (versionNumber.Patch == 1) {
                    if (!_config.itemsPresets.ContainsKey("biplaneitem_airfield")) _config.itemsPresets.Add("biplaneitem_airfield", new NamedItem {
                        shortname = "box.wooden.large", skin = 2776561072, name = "Biplane Airfield"
                    }
                    );
                    if (!_config.itemsPresets.ContainsKey("biplaneitem_bomber")) _config.itemsPresets.Add("biplaneitem_bomber", new NamedItem {
                        shortname = "box.wooden.large", skin = 2776561506, name = "Biplane Airfield"
                    }
                    );
                    if (!_config.itemsPresets.ContainsKey("biplaneitem_stormtrooper")) _config.itemsPresets.Add("biplaneitem_stormtrooper", new NamedItem {
                        shortname = "box.wooden.large", skin = 2776561787, name = "Biplane Airfield"
                    }
                    );
                    foreach (var pair in _config.biplanePresets) {
                        if (pair.Key == "biplane_airfield") {
                            pair.Value.customItemShortname = "biplaneitem_airfield";
                        }
                        else if (pair.Key == "biplane_bomber") {
                            pair.Value.customItemShortname = "biplaneitem_bomber";
                        }
                        else if (pair.Key == "biplane_stormtrooper") {
                            pair.Value.customItemShortname = "biplaneitem_stormtrooper";
                        }
                        else if (pair.Key == "biplane_default") {
                            pair.Value.bombs = false;
                            pair.Value.rockets = false;
                        }
                        pair.Value.permission = "";
                    }
                }
                if (versionNumber.Patch <= 2) {
                    _config.marker = new MarkerConfig {
                        enable = true, text = "Biplane seller"
                    }
                    ;
                }
                if (versionNumber.Patch <= 3) {
                    _config.allowIpckUp = true;
                    _config.spawnSetting.customSpawnPointsConfig = new CustomSpawnPointsConfig {
                        enableSpawn = false, presets = new Dictionary<string, float> {
                            ["biplane_airfield"]
                            = 100
                        }
                        , points = new List<LocationConfig>()
                    }
                    ;
                }
                if (versionNumber.Patch <= 4) {
                    foreach (string key in _config.biplanePresets.Keys) {
                        BiplaneSetting biplaneSetting = _config.biplanePresets[key];
                        biplaneSetting.biplaneControlSetting = new BiplaneControlSetting {
                            turningADSpeed = 1, turningMouseSpeed = 1,
                        }
                        ;
                    }
                }
                _config.version = Version.ToString();
                SaveConfig();
            }
        }
        IEnumerator SpawnCorountine() {
            while (true) {
                yield return CoroutineEx.waitForSeconds(UnityEngine.Random.Range(_config.spawnSetting.minRespawnTime, _config.spawnSetting.maxRespawnTime));
                SpawnBipaneAtMonuments();
                SpawnBipaneAtCustomPosition();
            }
        }
        IEnumerator SaveCorountine() {
            while (true) {
                saveBiplanes.Clear();
                foreach (BiplaneComponent biplane in biplanes) SaveBiplane(biplane);
                SaveData();
                yield return CoroutineEx.waitForSeconds(3600);
            }
        }
        void DefineMonumentAndPlayerLocation(BasePlayer player, out MonumentConfig monumentConfig, out LocationConfig locationConfig) {
            MonumentInfo monumentInfo = TerrainMeta.Path.Monuments.FirstOrDefault(x => _config.spawnSetting.monumentSpawnSettings.ContainsKey(x.name) && Vector3.Distance(player.transform.position, x.transform.position) < x.Bounds.size.x);
            if (monumentInfo == null) {
                PrintToChat(player, "The monument was not found in the config.To add it, use the <addbiplanemonument> command ");
                monumentConfig = null;
                locationConfig = null;
                return;
            }
            MonumentConfig newMonumentConfig = _config.spawnSetting.monumentSpawnSettings[monumentInfo.name];
            LocationConfig newLocationConfig = new LocationConfig {
                position = monumentInfo.transform.InverseTransformPoint(player.transform.position).ToString(), rotation = (player.viewAngles - monumentInfo.transform.rotation.eulerAngles).y.ToString()
            }
            ;
            monumentConfig = newMonumentConfig;
            locationConfig = newLocationConfig;
        }
        void SpawnSellersAtMonuments() {
            foreach (MonumentInfo monumentInfo in monuments) {
                MonumentConfig monumentConfig = _config.spawnSetting.monumentSpawnSettings[monumentInfo.name];
                if (!monumentConfig.enableSeller || monumentConfig.sellerLocation == null) continue;
                Vector3 position = monumentInfo.transform.TransformPoint(monumentConfig.sellerLocation.position.ToVector3());
                VehicleVendor seller = GameManager.server.CreateEntity("assets/prefabs/npc/bandit/shopkeepers/bandit_conversationalist.prefab", position, monumentInfo.transform.rotation * Quaternion.Euler(new Vector3(0, float.Parse(monumentConfig.sellerLocation.rotation), 0))) as VehicleVendor;
                seller.enableSaving = false;
                seller.Spawn();
                if (!_config.marker.enable) sellers.Add(new SellerData(seller, monumentConfig.sellerName, monumentInfo.transform, monumentInfo.name, null));
                else sellers.Add(new SellerData(seller, monumentConfig.sellerName, monumentInfo.transform, monumentInfo.name, CreateMapMarker(position)));
            }
        }
        void SpawnBipaneAtMonuments() {
            foreach (MonumentInfo monumentInfo in monuments) {
                MonumentConfig monumentConfig = _config.spawnSetting.monumentSpawnSettings[monumentInfo.name];
                if (monumentConfig.points.Count == 0 || monumentConfig.presets.Count == 0 || !monumentConfig.presets.Values.Any(x => x > 0)) continue;
                LocationConfig locationConfig = monumentConfig.points.GetRandom();
                string biplanePreset = "";
                while (String.IsNullOrEmpty(biplanePreset)) {
                    foreach (var pair in monumentConfig.presets) {
                        if (UnityEngine.Random.Range(0f, 100f) <= pair.Value) {
                            biplanePreset = pair.Key;
                            break;
                        }
                    }
                }
                Vector3 position = monumentInfo.transform.TransformPoint(locationConfig.position.ToVector3());
                if (biplanes.Any(x => Vector3.Distance(x.transform.position, position) < 10f)) continue;
                CreateBiplane(position, monumentInfo.transform.rotation * Quaternion.Euler(new Vector3(0, float.Parse(locationConfig.rotation), 0)), biplanePreset);
            }
        }
        void SpawnBipaneAtCustomPosition() {
            if (!_config.spawnSetting.customSpawnPointsConfig.enableSpawn) return;
            foreach (LocationConfig locationConfig in _config.spawnSetting.customSpawnPointsConfig.points) {
                string biplanePreset = "";
                while (String.IsNullOrEmpty(biplanePreset)) {
                    foreach (var pair in _config.spawnSetting.customSpawnPointsConfig.presets) {
                        if (UnityEngine.Random.Range(0f, 100f) <= pair.Value) {
                            biplanePreset = pair.Key;
                            break;
                        }
                    }
                }
                if (biplanes.Any(x => Vector3.Distance(x.transform.position, locationConfig.position.ToVector3()) < 10f)) continue;
                CreateBiplane(locationConfig.position.ToVector3(), Quaternion.Euler(0, Convert.ToSingle(locationConfig.rotation), 0), biplanePreset);
            }
        }
        void CreateBiplane(Vector3 position, Quaternion rotation, string presetName, bool firstSpawn = true, bool addModule = true) {
            ModularCar car = GameManager.server.CreateEntity("assets/content/vehicles/modularcar/3module_car_spawned.entity.prefab", position, rotation) as ModularCar;
            BiplaneComponent biplaneComponent = car.gameObject.AddComponent<BiplaneComponent>();
            car.spawnSettings.useSpawnSettings = false;
            car.Spawn();
            biplaneComponent.Init(presetName, firstSpawn, addModule);
            biplanes.Add(biplaneComponent);
        }
        void SaveBiplane(BiplaneComponent biplaneComponent) {
            if (biplaneComponent == null || !biplaneComponent.modularCar.IsExists()) return;
            SaveBiplaneData saveBiplaneData = new SaveBiplaneData(biplaneComponent.modularCar.net.ID.Value, biplaneComponent.presetName, 0);
            foreach (Item item in biplaneComponent.container.inventory.itemList) {
                if (item == null) continue;
                SaveItemData saveItemData = new SaveItemData(item.info.shortname, item.name, item.amount, item.skin, item.condition);
                BaseProjectile projectile = item.GetHeldEntity() as BaseProjectile;
                if (projectile != null) {
                    saveItemData.projectileData = new ProjectileData(projectile.primaryMagazine.ammoType.shortname, projectile.primaryMagazine.contents);
                    foreach (Item modItem in item.contents.itemList) saveItemData.projectileData.mods.Add(modItem.info.shortname);
                }
                saveBiplaneData.items.Add(saveItemData);
            }
            saveBiplanes.Add(saveBiplaneData);
        }
        void LoadBiplane(ModularCar modularCar, SaveBiplaneData saveBiplaneData) {
            BiplaneComponent biplaneComponent = modularCar.gameObject.AddComponent<BiplaneComponent>();
            if (saveBiplaneData.keyIndex != 0) {
                //modularCar.carLock.AddALock();
                //modularCar.carLock.LockID = saveBiplaneData.keyIndex;
            }
            biplaneComponent.Init(saveBiplaneData.biplanePrefab, false);
            biplanes.Add(biplaneComponent);
            if (saveBiplaneData.items.Count > 0) timer.In(1f, () => {
                foreach (SaveItemData saveItemData in saveBiplaneData.items) {
                    Item newItem = ItemManager.CreateByName(saveItemData.shortname, saveItemData.amount, saveItemData.skin);
                    newItem.condition = saveItemData.condition;
                    if (saveItemData.customName != null) newItem.name = saveItemData.customName;
                    if (!newItem.MoveToContainer(biplaneComponent.container.inventory)) {
                        newItem.Remove();
                        continue;
                    }
                    if (saveItemData.projectileData != null) {
                        BaseProjectile projectile = newItem.GetHeldEntity() as BaseProjectile;
                        if (projectile != null) {
                            if (saveItemData.projectileData.ammoShortname != "") projectile.primaryMagazine.ammoType = ItemManager.FindItemDefinition(saveItemData.projectileData.ammoShortname);
                            projectile.primaryMagazine.contents = saveItemData.projectileData.ammoAmount;
                            foreach (string shortname in saveItemData.projectileData.mods) {
                                ItemDefinition itemDefinition = ItemManager.FindItemDefinition(shortname);
                                if (itemDefinition != null) newItem.contents.AddItem(itemDefinition, 1);
                            }
                        }
                    }
                }
            }
            );
        }
        VendingMachineMapMarker CreateMapMarker(Vector3 position) {
            VendingMachineMapMarker vendingMarker = GameManager.server.CreateEntity("assets/prefabs/deployable/vendingmachine/vending_mapmarker.prefab", position) as VendingMachineMapMarker;
            vendingMarker.enableSaving = false;
            vendingMarker.Spawn();
            vendingMarker.markerShopName = _config.marker.text;
            return vendingMarker;
        }
        private static void CopySerializableFields<T>(T src, T dst) {
            FieldInfo[] srcFields = typeof(T).GetFields(BindingFlags.Public | BindingFlags.Instance);
            foreach (FieldInfo field in srcFields) {
                object value = field.GetValue(src);
                field.SetValue(dst, value);
            }
        }
#endregion Methods
#region Classes
        class BiplaneComponent : FacepunchBehaviour {
            internal Coroutine controlCorountine;
            internal string presetName;
            internal BiplaneSetting biplaneSetting;
            internal StorageContainer container;
            internal ModularCar modularCar;
            internal BaseMountable fakeSeat;
            internal List<BaseEntity> subEntities = new List<BaseEntity>();
            List<BaseEntity> rotors = new List<BaseEntity>();
            Rigidbody rigidbody;
            internal BaseMountable pilotSeat;
            List<BaseEntity> rockets = new List<BaseEntity>();
            bool active = true;
            internal bool grounded = true;
            bool engineOn = false;
            int lastFuelAmount = 0;
            float weaonDelay = 1f;
            bool leftRocket = true;
            internal void Init(string presetName, bool firstSpawn = true, bool addModule = true) {
                this.presetName = presetName;
                biplaneSetting = ins._config.biplanePresets[presetName];
                modularCar = GetComponent<ModularCar>();
                modularCar.spawnSettings.useSpawnSettings = false;
                modularCar.Inventory.ModuleContainer.capacity = 1;
                modularCar.Inventory.ModuleContainer.SetOnlyAllowedItem(ItemManager.FindItemDefinition("vehicle.1mod.engine"));
                foreach (BaseVehicle.MountPointInfo mountPointInfo in modularCar.mountPoints) mountPointInfo.mountable.Kill();
                modularCar.mountPoints.Clear();
                rigidbody = modularCar.rigidBody;
                rigidbody.drag = 0.1f;
                Invoke(() => Buid(firstSpawn, addModule), 0.1f);
            }
            void Buid(bool firstSpawn, bool addModule) {
                if (firstSpawn) {
                    Item moduleItem = ItemManager.CreateByName("vehicle.1mod.engine");
                    modularCar.TryAddModule(moduleItem, 0);
                    if (addModule) Invoke(EngineBuild, 0.25f);
                }
                SpawnSubEntity();
                SpawnSeat();
                SpawnRotor();
            }
            void EngineBuild() {
                if (biplaneSetting.fuelAmount > 0) {
                    StorageContainer fuelContainer = GetFuelContainer(modularCar);
                    if (fuelContainer != null) {
                        fuelContainer.inventory.AddItem(fuelContainer.allowedItem, biplaneSetting.fuelAmount);
                        fuelContainer.isLootable = false;
                        UpdateFuelSystem(modularCar);
                        // Call to update the fuel system after adding fuel
                    }
                }
                if (biplaneSetting.engineComponents) {
                    foreach (BaseVehicleModule module in modularCar.AttachedModuleEntities) {
                        VehicleModuleEngine engineModule = module as VehicleModuleEngine;
                        if (engineModule == null) continue;
                        Rust.Modular.EngineStorage engineStorage = engineModule.GetContainer() as Rust.Modular.EngineStorage;
                        if (engineStorage == null) continue;
                        ItemContainer inventory = engineStorage.inventory;
                        for (var i = 0; i < inventory.capacity; i++) {
                            ItemModEngineItem output;
                            if (!engineStorage.allEngineItems.TryGetItem(biplaneSetting.engineComponentsLvl, engineStorage.slotTypes[i], out output)) continue;
                            ItemDefinition component = output.GetComponent<ItemDefinition>();
                            Item item = ItemManager.Create(component);
                            if (item == null) continue;
                            item.conditionNormalized = 100;
                            item.MoveToContainer(engineStorage.inventory, i, allowStack : false);
                        }
                        engineModule.RefreshPerformanceStats(engineStorage);
                        return;
                    }
                }
            }
            StorageContainer GetFuelContainer(BaseModularVehicle vehicle) {
                // Accessing the fuel container through available modules and properties
                foreach (BaseVehicleModule module in vehicle.AttachedModuleEntities) {
                    if (module is VehicleModuleEngine engineModule) {
                        // Check if the engine module has any child entities that are StorageContainer
                        foreach (BaseEntity child in engineModule.children) {
                            if (child is StorageContainer container && container.allowedItem != null && container.allowedItem.shortname == "lowgradefuel") {
                                return container;
                            }
                        }
                    }
                }
                return null;
            }
            void UpdateFuelSystem(BaseModularVehicle vehicle) {
                // This method triggers the fuel system to recognize the new fuel level
                IFuelSystem fuelSystem = vehicle.GetFuelSystem();
                if (fuelSystem != null) {
                    // This is a hypothetical method.Replace with the actual method to update the fuel system if available
                    // fuelSystem.UpdateFuelLevel();
                    // or fuelSystem.Refresh(); or similar
                    // Ensure to call the right method that updates or refreshes the fuel system
                }
            }
            void SpawnRotor() {
                foreach (BaseEntity rotor in rotors) if (rotor != null && !rotor.IsDestroyed) rotor.Kill();
                rotors.Clear();
                if (rotors.Count == 0) {
                    foreach (RotorData rotorData in ins.rotorPositions) {
                        BaseEntity entity = GameManager.server.CreateEntity("assets/prefabs/weapons/sword big/longsword.entity.prefab", Vector3.zero, Quaternion.identity, false);
                        entity.enableSaving = false;
                        entity.SetParent(modularCar);
                        entity.transform.localPosition = rotorData.position;
                        entity.transform.localEulerAngles = rotorData.rotation;
                        entity.SetFlag(BaseEntity.Flags.Reserved8, true);
                        entity.Spawn();
                        rotors.Add(entity);
                        if (rotorData.hide) entity.limitNetworking = true;
                    }
                }
                else {
                    for (int i = 0; i < ins.rotorPositions.Count; i++) {
                        if (i >= rotors.Count) return;
                        BaseEntity rotor = rotors[i];
                        if (!rotor.IsExists()) continue;
                        if (ins.rotorPositions[i].hide) rotor.limitNetworking = true;
                        else rotor.limitNetworking = false;
                    }
                }
            }
            void SpawnSubEntity() {
                foreach (SubEntityData subEntityData in ins.subEntityDatas) {
                    if (subEntityData.type == 4 && !biplaneSetting.rockets) continue;
                    BaseEntity entity = GameManager.server.CreateEntity(subEntityData.name, Vector3.zero, Quaternion.identity, false);
                    entity.enableSaving = false;
                    if (subEntityData.type == 0) {
                        DecorWing newEntity = entity.gameObject.AddComponent<DecorWing>();
                        CopySerializableFields(entity, newEntity);
                        UnityEngine.Object.DestroyImmediate(entity, true);
                        newEntity.gameObject.AwakeFromInstantiate();
                        newEntity.enableSaving = false;
                        newEntity.SetParent(modularCar);
                        newEntity.transform.localPosition = subEntityData.position;
                        newEntity.transform.localEulerAngles = subEntityData.rotation;
                        newEntity.Spawn();
                        newEntity.InitializeHealth(200, 200);
                        newEntity.SetFlag(BaseEntity.Flags.Reserved7, true);
                        newEntity.SetFlag(BaseEntity.Flags.On, true);
                        newEntity.SetFlag(BaseEntity.Flags.Busy, true);
                        Rigidbody entityRigidbody = newEntity.GetComponent<Rigidbody>();
                        if (entityRigidbody != null) Destroy(entityRigidbody);
                        subEntities.Add(newEntity);
                    }
                    else if (subEntityData.type == 1) {
                        Kayak kayak = entity as Kayak;
                        BaseVehicle newEntity = entity.gameObject.AddComponent<BaseVehicle>();
                        CopySerializableFields(kayak, newEntity);
                        UnityEngine.Object.DestroyImmediate(entity, true);
                        newEntity.gameObject.AwakeFromInstantiate();
                        newEntity.enableSaving = false;
                        newEntity.SetParent(modularCar);
                        newEntity.transform.localPosition = subEntityData.position;
                        newEntity.transform.localEulerAngles = subEntityData.rotation;
                        Rigidbody entityRigidbody = newEntity.GetComponent<Rigidbody>();
                        if (entityRigidbody != null) Destroy(entityRigidbody);
                        newEntity.isMobile = false;
                        newEntity.Spawn();
                        subEntities.Add(newEntity);
                        newEntity.SetFlag(BaseEntity.Flags.On, true);
                        foreach (var a in newEntity.mountPoints) {
                            a.mountable.SetParent(modularCar);
                            modularCar.mountPoints.Add(a);
                            a.mountable.transform.localPosition = new Vector3(a.mountable.transform.localPosition.x, a.mountable.transform.localPosition.y + 0.68f, a.mountable.transform.localPosition.z);
                            a.mountable.allowHeadLook = false;
                            newEntity.SetFlag(BaseEntity.Flags.Reserved8, true);
                            if (fakeSeat == null) fakeSeat = a.mountable;
                            else a.isDriver = false;
                        }
                    }
                    else {
                        entity.SetParent(modularCar);
                        entity.transform.localPosition = subEntityData.position;
                        entity.transform.localEulerAngles = subEntityData.rotation;
                        if (subEntityData.type == 2 || subEntityData.type >= 4) entity.SetFlag(BaseEntity.Flags.Reserved8, true);
                        entity.Spawn();
                        Rigidbody entityRigidbody = entity.GetComponent<Rigidbody>();
                        if (entityRigidbody != null) Destroy(entityRigidbody);
                        subEntities.Add(entity);
                        if (subEntityData.type == 4) rockets.Add(entity);
                        if (subEntityData.type == 3) {
                            container = entity as StorageContainer;
                            container.inventory.capacity = biplaneSetting.countSlots;
                        }
                    }
                }
            }
            void SpawnSeat() {
                BaseMountable seat = GameManager.server.CreateEntity("assets/prefabs/vehicle/seats/miniheliseat.prefab") as BaseMountable;
                seat.enableSaving = false;
                seat.SetParent(modularCar, true, false);
                seat.transform.localPosition = new Vector3(0f, 0.45f, 0.324f);
                seat.transform.localEulerAngles = Vector3.zero;
                seat.Spawn();
                modularCar.mountPoints.Add(new BaseVehicle.MountPointInfo {
                    pos = seat.transform.position, rot = seat.transform.eulerAngles, isDriver = true, mountable = seat, prefab = null
                }
                );
                pilotSeat = seat;
            }
            internal void MountPlayer(BasePlayer player) {
                if (pilotSeat._mounted == null) pilotSeat.MountPlayer(player);
            }
            internal void UnSleep() {
                if (controlCorountine == null) controlCorountine = ServerMgr.Instance.StartCoroutine(ControlCorountine());
            }
            IEnumerator ControlCorountine() {
                lastFuelAmount = 0;
                while (!grounded || pilotSeat._mounted != null) {
                    bool checkGroung = modularCar.wheelFR.wheelCollider.isGrounded || modularCar.wheelFL.wheelCollider.isGrounded || modularCar.wheelRR.wheelCollider.isGrounded || modularCar.wheelRL.wheelCollider.isGrounded || Vector3.Angle(modularCar.transform.forward, rigidbody.velocity) > 90;
                    if (checkGroung != grounded) {
                        grounded = checkGroung;
                        if (grounded) {
                            rigidbody.maxAngularVelocity = 0.7f;
                            modularCar.carSettings.maxSteerAngle = 35f;
                        }
                        else {
                            rigidbody.maxAngularVelocity = 0.3f;
                            modularCar.carSettings.maxSteerAngle = 0;
                        }
                    }
                    bool checkEngine = modularCar.engineController.IsOn;
                    if (checkEngine != engineOn) {
                        engineOn = checkEngine;
                        if (!engineOn) SpawnRotor();
                    }
                    if (engineOn) {
                        foreach (BaseEntity rotor in rotors) {
                            if (UnityEngine.Random.Range(0, 2) < 1) {
                                rotor.limitNetworking = true;
                                rotor.limitNetworking = false;
                            }
                        }
                    }
                    BasePlayer player = pilotSeat._mounted;
                    if (player != null) {
                        UpdateGui(player);
                        float leftRight = player.serverInput.MouseDelta().x;
                        if (leftRight > 10) leftRight = 10;
                        if (leftRight < -10) leftRight = -10;
                        if (ins._config.invertX) leftRight = -leftRight;
                        float upDown = player.serverInput.MouseDelta().y;
                        if (upDown > 10) upDown = 10;
                        if (upDown < -10) upDown = -10;
                        if (ins._config.invertY) upDown = -upDown;
                        float speedScale = 1.25f * rigidbody.velocity.magnitude / biplaneSetting.maxVelosity;
                        if (speedScale > 1) speedScale = 1;
                        if (grounded) {
                            if (upDown < 0 || rigidbody.velocity.magnitude < 10) upDown = 0;
                            rigidbody.AddForce(Vector3.up * rigidbody.velocity.magnitude * 1000);
                        }
                        if (player.serverInput.IsDown(BUTTON.FORWARD) && (rigidbody.velocity.magnitude < biplaneSetting.maxVelosity) && engineOn) rigidbody.AddForce(modularCar.transform.forward.normalized * biplaneSetting.force);
                        if (upDown != 0) rigidbody.AddTorque(modularCar.transform.right * upDown * -4000 * speedScale * biplaneSetting.biplaneControlSetting.turningMouseSpeed);
                        if (!grounded) {
                            rigidbody.AddTorque(modularCar.transform.up * leftRight * 4000 * speedScale * biplaneSetting.biplaneControlSetting.turningMouseSpeed);
                            if (player.serverInput.IsDown(BUTTON.LEFT)) rigidbody.AddTorque(modularCar.transform.forward * 4000 * speedScale * biplaneSetting.biplaneControlSetting.turningADSpeed);
                            if (player.serverInput.IsDown(BUTTON.RIGHT)) rigidbody.AddTorque(modularCar.transform.forward * -4000 * speedScale * biplaneSetting.biplaneControlSetting.turningADSpeed);
                        }
                    }
                    Vector2 vector2 = new Vector2(rigidbody.velocity.x, rigidbody.velocity.z);
                    if (!gro
// ... [Code preview truncated due to length. Full source in attached file] ...

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

Другие ресурсы пользователя 15FPS

Сверху