• Добрый день, если вы испытываете проблемы с пополнением баланса, свяжитесь с @MrFallen.

Помогите Проблема с плагином по вызову scraptransporthelicopter.

DoKZaMmer

22 Окт 2023
243
1
14
23
30
Всем - утро, день, вечер добрый!
В общем, ситуация следующая...
Скачал плагин на вызов по команде чата мини-коптера(/mymini), далее решил его переписать ещё и на вызов транспортного вертолёта, всё вроде как "получилось".
С одной оговоркой, "вроде".
При вызове транспортного вертолёта командой "/myheli, он вызывается, но не отображается, есть его коллизия, я в неё упираюсь, но физически его не видно и не как нельзя взаимодействовать с ним. Так же есть звук того, что он заспавнился. Потом, после очередных моих "манипуляций" и попыток как-то его увидеть, я поглубже изменил плагин, но после этого, команда вообще перестала срабатывать, а сервер при этом не каких ошибок мне не выявлял. Я, решил откатить всё как было изначально, чтобы начинать менять плагин постепенно и понять, где моя ошибка. Дак, теперь при вводе команды на вызов вертолёта(/myheli) мне сервер пишет такую ошибку: Couldn't find prefab "assets/content/vehicles/scraphelicarrier/scraptransporthelicopter.prefab", хотя папку в префабы, я вообще не заходил не разу. Так же добавлю, что плагин загружается и перезагружается после каких либо изменений в нём, без ошибок, но по какой-то не понятной для меня причине, он пишет мне ошибку по префабам. Так же расскажу ещё один момент, при попытке вызова этого же вертолёта через F1, он появляется и отображается как и должен появляться и отображаться, так же он появляется и отображается при его покупке в городе бандитов за скрап. Но, вот через плагин, он вообще не в какую не хочется вызываться. Кто-то может сталкивался с похожим или есть опыт в решение похожих проблем, буду рад выслушать.
Заранее, благодарю за помощь.
 
Minicopter heli = GameManager.server.CreateEntity(assets/content/vehicles/minicopter/minicopter.entity.prefab, pos, new Quaternion()) as Minicopter;

ScrapTransportHelicopter heli = GameManager.server.CreateEntity("assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", pos, new Quaternion()) as ScrapTransportHelicopter;

AttackHelicopter heli = GameManager.server.CreateEntity(assets/content/vehicles/attackhelicopter/attackhelicopter.entity.prefab, pos, new Quaternion(), true) as AttackHelicopter;


Далее думаю разберешься
 
  • Мне нравится
Реакции: DoKZaMmer
Minicopter heli = GameManager.server.CreateEntity(assets/content/vehicles/minicopter/minicopter.entity.prefab, pos, new Quaternion()) as Minicopter;

ScrapTransportHelicopter heli = GameManager.server.CreateEntity("assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", pos, new Quaternion()) as ScrapTransportHelicopter;

AttackHelicopter heli = GameManager.server.CreateEntity(assets/content/vehicles/attackhelicopter/attackhelicopter.entity.prefab, pos, new Quaternion(), true) as AttackHelicopter;


Далее думаю разберешься
Я нашёл в плагине две таких строчки, заменил, а теперь он мне жалуется на это:

Error while compiling SpawnMini: The name 'assets' does not exist in the current context | Line: 487, Pos: 63

Хотя, что в оригинале, что в моём плагине, эта линия вообще ПУСТАЯ...
Вот вырезка из плагина, чтобы ты понял наглядно как выглядит этот модуль.

485 ScrapTransportHelicopter heli = GameManager.server.CreateEntity("assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", pos, new Quaternion()) as ScrapTransportHelicopter;
486 if (mini == null) return;
487
488 mini.OwnerID = player.userID;
489 mini.startHealth = _config.spawnHealth;
490 mini.Spawn();
 
Так же, есть строчка в этом плагине, как я понял, которая отвечает за префабы.

634 [JsonProperty("AssetPrefab")]
635 public string assetPrefab = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab";

Может, я настолько глуп, что делаю что-то не так. Если не сложно, дай пожалуйста развёрнутый ответ, заранее спасибо!
 
Так же, есть строчка в этом плагине, как я понял, которая отвечает за префабы.

634 [JsonProperty("AssetPrefab")]
635 public string assetPrefab = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab";

Может, я настолько глуп, что делаю что-то не так. Если не сложно, дай пожалуйста развёрнутый ответ, заранее спасибо!
чтобы все заработало корректно, придется переписать половину скрипта.
Спавн командой это дело 5 секунд, но деспавн и прочая шняга нуждается в оптимизации под 2 тс
 
  • Мне нравится
Реакции: DoKZaMmer
чтобы все заработало корректно, придется переписать половину скрипта.
Спавн командой это дело 5 секунд, но деспавн и прочая шняга нуждается в оптимизации под 2 тс
Не кто не спорит, я итак его уже переписал под транспортный вертолёт, просто он либо вызывается но его не видно(есть его коллизия и звук что он вызвался по команде), либо, он вообще не вызывается, а сервер говорит про ошибку префаба.
Вот, я и хочу понять, в чём моя ошибка.
 
C#:
        [ChatCommand("myheli")]
        private void SpawnCommandScrapHelicopter(BasePlayer player)
        {
            Vector3 pos = player.GetNetworkPosition();
            string heliPrefabPath = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab";

            ScrapTransportHelicopter heli = GameManager.server.CreateEntity(heliPrefabPath, pos, new Quaternion()) as ScrapTransportHelicopter;

            if (heli != null)
                heli.Spawn();
            else
                player.ChatMessage("Произошла ошибка при спавне scraptransporthelicopter!");

            player.ChatMessage($"хеликоптер хеликоптер, паракоптер паракоптер");
        }

может путь был не правильный, нашел актуальный через prefab sniffer 1697979097941.png
 
  • Мне нравится
Реакции: DoKZaMmer
C#:
        [ChatCommand("myheli")]
        private void SpawnCommandScrapHelicopter(BasePlayer player)
        {
            Vector3 pos = player.GetNetworkPosition();
            string heliPrefabPath = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab";

            ScrapTransportHelicopter heli = GameManager.server.CreateEntity(heliPrefabPath, pos, new Quaternion()) as ScrapTransportHelicopter;

            if (heli != null)
                heli.Spawn();
            else
                player.ChatMessage("Произошла ошибка при спавне scraptransporthelicopter!");

            player.ChatMessage($"хеликоптер хеликоптер, паракоптер паракоптер");
        }

может путь был не правильный, нашел актуальный через prefab sniffer 1697979097941.png
Интересные строчки у тебя в плагине...
У меня почему-то вот такие:
Код:
[ChatCommand("myheli")]
        private void SpawnCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, _Spawnheli))
            {
                player.ChatMessage(lang.GetMessage("heli_perm", this, player.UserIDString));
                return;
            }

            var heli = FindPlayerheli(player);
            if (heli != null)
            {
                if (_config.autoFetch && permission.UserHasPermission(player.UserIDString, _fetchheli))
                {
                    FetchInternal(player, heli);
                }
                else
                {
                    player.ChatMessage(lang.GetMessage("heli_current", this, player.UserIDString));
                }
У тебя получается более проработанный плагин, но опять же... По моим строчкам, у меня коптер вызывается, а транспортный вертолёт, к сожалению нет.
 
Интересные строчки у тебя в плагине...
У меня почему-то вот такие:
Код:
[ChatCommand("myheli")]
        private void SpawnCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, _Spawnheli))
            {
                player.ChatMessage(lang.GetMessage("heli_perm", this, player.UserIDString));
                return;
            }

            var heli = FindPlayerheli(player);
            if (heli != null)
            {
                if (_config.autoFetch && permission.UserHasPermission(player.UserIDString, _fetchheli))
                {
                    FetchInternal(player, heli);
                }
                else
                {
                    player.ChatMessage(lang.GetMessage("heli_current", this, player.UserIDString));
                }
У тебя получается более проработанный плагин, но опять же... По моим строчкам, у меня коптер вызывается, а транспортный вертолёт, к сожалению нет.
ничего у меня не проработано, я просто отдельно метод написал :)
я думаю ты дальше сам напишешь требующийся код?
 
  • Мне нравится
Реакции: DoKZaMmer
Интересные строчки у тебя в плагине...
У меня почему-то вот такие:
Код:
[ChatCommand("myheli")]
        private void SpawnCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, _Spawnheli))
            {
                player.ChatMessage(lang.GetMessage("heli_perm", this, player.UserIDString));
                return;
            }

            var heli = FindPlayerheli(player);
            if (heli != null)
            {
                if (_config.autoFetch && permission.UserHasPermission(player.UserIDString, _fetchheli))
                {
                    FetchInternal(player, heli);
                }
                else
                {
                    player.ChatMessage(lang.GetMessage("heli_current", this, player.UserIDString));
                }
У тебя получается более проработанный плагин, но опять же... По моим строчкам, у меня коптер вызывается, а транспортный вертолёт, к сожалению нет.
ты как я понял тут не все вставил
после этого идет блок else
в него вставь вызов метода который скинул я, и все у тебя заработает
 
  • Мне нравится
Реакции: DoKZaMmer
ничего у меня не проработано, я просто отдельно метод написал :)
я думаю ты дальше сам напишешь требующийся код?
Ну да, я вижу, что у тебя метод яснее выглядит)
Ты наверное будешь делать "рука лицо", но нет, на столько познаний в компиляции у меня к сожалению нет, я вот сейчас всячески пытал твой код, но сервер ругается, что я делаю что-то не так..
 
ты как я понял тут не все вставил

после этого идет блок else
в него вставь вызов метода который скинул я, и все у тебя заработает
Вот, смотри..
Сейчас подзабил на транспотник, занялся атакующим вертолётом, дак он 1в1, как транспортный и коптер, в плагине прописан, только они оба спавнятся без ошибок и проблем, а вот именно траспортник не в какую не хочет, всё так же продолжает ругаться на префаб свой, может у меня префаб слетел или повредился? Просто, у меня всё работает как надо, только он не хочет не в какую... Опять же, напомню, по командам из F1 и с бандитки, он у меня вызывается, покупается и отображается адекватно как и должен... Странно для меня всё это...
Так же, префаб я перепроверил, как выше в 4 сообщении он у меня написан, так же он и написан в твоём скрине, 1в1, но... Конкретно на префаб сервер всё равно продолжает ругаться... Опять же, он начинается ругаться не когда загружается там или если, я вношу изменения в него, как раз таки, когда, я всё это делаю, он загружается-перезагружается без каких либо проблем. Но, как только зайдя на сервер, я начинаю прописывать команду /myheli, в игре не чего не происходит, а сервер пишет ошибку по префабу. Я так думаю, если я разберусь с префабом, проблема сразу уйдёт, но теперь вопрос следующего характера, как решать его?!
 
Интересные строчки у тебя в плагине...
У меня почему-то вот такие:
Код:
[ChatCommand("myheli")]
        private void SpawnCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, _Spawnheli))
            {
                player.ChatMessage(lang.GetMessage("heli_perm", this, player.UserIDString));
                return;
            }

            var heli = FindPlayerheli(player);
            if (heli != null)
            {
                if (_config.autoFetch && permission.UserHasPermission(player.UserIDString, _fetchheli))
                {
                    FetchInternal(player, heli);
                }
                else
                {
                    player.ChatMessage(lang.GetMessage("heli_current", this, player.UserIDString));
                }
У тебя получается более проработанный плагин, но опять же... По моим строчкам, у меня коптер вызывается, а транспортный вертолёт, к сожалению нет.
class MyHeli : RustPlugin
{
private static readonly int GlobalLayerMask = LayerMask.GetMask("Construction", "Default", "Deployed",
"Resource", "Terrain", "Water", "World");

[ChatCommand("heli")]
private void SpawnCommand(BasePlayer player, string command, string[] args)
{
float startHealth = 700f;
float fuelPerSec = 0.5f;
if (player == null) return; //проверка на сущ.игрока
RaycastHit hit;
if (UnityEngine.Physics.Raycast(player.eyes.HeadRay(), out hit, Mathf.Infinity, GlobalLayerMask))
{
Vector3 pos = hit.point + Vector3.up * 1f;
ScrapTransportHelicopter heli = GameManager.server.CreateEntity("assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", pos, new Quaternion(), true) as ScrapTransportHelicopter;
if (heli == null) return;
heli.OwnerID = player.userID;
heli.startHealth = startHealth;
heli.fuelPerSec = fuelPerSec;
heli.Spawn();
}
}
}
 
  • Мне нравится
Реакции: DoKZaMmer
class MyHeli : RustPlugin
{
private static readonly int GlobalLayerMask = LayerMask.GetMask("Construction", "Default", "Deployed",
"Resource", "Terrain", "Water", "World");

[ChatCommand("heli")]
private void SpawnCommand(BasePlayer player, string command, string[] args)
{
float startHealth = 700f;
float fuelPerSec = 0.5f;
if (player == null) return; //проверка на сущ.игрока
RaycastHit hit;
if (UnityEngine.Physics.Raycast(player.eyes.HeadRay(), out hit, Mathf.Infinity, GlobalLayerMask))
{
Vector3 pos = hit.point + Vector3.up * 1f;
ScrapTransportHelicopter heli = GameManager.server.CreateEntity("assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", pos, new Quaternion(), true) as ScrapTransportHelicopter;
if (heli == null) return;
heli.OwnerID = player.userID;
heli.startHealth = startHealth;
heli.fuelPerSec = fuelPerSec;
heli.Spawn();
}
}
}
Вы же понимаете, что вы мне скидываете куски своего КАСТОМНОГО кода и чтобы они заработали правильно у меня, мне нужно их логически соединить со своим, таким же, кастомным кодом. Но проблема вся заключается в том, что, я не обладаю такими обширными знаниями, чтобы все петли объединить в одну. Мне нужно, либо ваша сторона кода(полная), либо моя, допустим объединенная с вашим кодом, чтобы добиться нужного результата, а иначе, победы, лично мне, не видать в моей проблеме.
Давайте, поступим так, если у вас есть возможность и желание, помогите мне с моим плагином, я отправлю его следующим 1 сообщением целиком, чтобы было удобно с ним отработать вам.
Заранее, как всегда благодарю Вас за всю оказанную мне помощь!
 
Код:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Oxide.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;


namespace Oxide.Plugins
{
    [Info("Spawn heli", "SpooksAU", "2.12.3")]
    [Description("Spawn a heli!")]
    class Spawnheli : RustPlugin
    {
        private SaveData _data;
        private PluginConfig _config;


        /* EDIT PERMISSIONS HERE */
        private readonly string _Spawnheli = "Spawnheli.heli";
        private readonly string _noCooldown = "Spawnheli.nocd";
        private readonly string _noHeli = "Spawnheli.noHeli";
        private readonly string _fetchheli = "Spawnheli.fheli";
        private readonly string _noFuel = "Spawnheli.unlimitedfuel";
        private readonly string _noDecay = "Spawnheli.nodecay";
        private readonly string _permissionFuelFormat = "Spawnheli.fuel.{0}";


        #region Hooks


        private void Init()
        {
            permission.RegisterPermission(_Spawnheli, this);
            permission.RegisterPermission(_noCooldown, this);
            permission.RegisterPermission(_noHeli, this);
            permission.RegisterPermission(_fetchheli, this);
            permission.RegisterPermission(_noFuel, this);
            permission.RegisterPermission(_noDecay, this);


            foreach (var perm in _config.spawnPermissionCooldowns)
                permission.RegisterPermission(perm.Key, this);


            foreach (var perm in _config.fetchPermissionCooldowns)
            {
                // Allow server owners to use the same permission for spawn and fetch.
                if (!permission.PermissionExists(perm.Key))
                {
                    permission.RegisterPermission(perm.Key, this);
                }
            }


            foreach (var fuelAmount in _config.fuelAmountsRequiringPermission)
                permission.RegisterPermission(GetFuelPermission(fuelAmount), this);


            if (!Interface.Oxide.DataFileSystem.ExistsDatafile(Name))
                Interface.Oxide.DataFileSystem.GetDatafile(Name).Save();


            LoadSaveData();


            if (!_config.ownerOnly)
                Unsubscribe(nameof(CanMountEntity));


            if (!_config.destroyOnDisconnect)
            {
                Unsubscribe(nameof(OnPlayerDisconnected));
                Unsubscribe(nameof(OnEntityDismounted));
            }
        }


        void OnServerInitialized()
        {
            foreach (var heli in BaseNetworkable.serverEntities.OfType<ScrapTransportHelicopter>())
            {
                if (IsPlayerOwned(heli) && heli.OwnerID != 0 && permission.UserHasPermission(heli.OwnerID.ToString(), _noFuel))
                {
                    EnableUnlimitedFuel(heli);
                }
            }
        }


        void Unload() => WriteSaveData();


        void OnServerSave() => WriteSaveData();


        void OnNewSave()
        {
            _data.playerheli.Clear();
            _data.spawnCooldowns.Clear();
            _data.fetchCooldowns.Clear();
            WriteSaveData();
        }


        void OnEntityKill(ScrapTransportHelicopter heli)
        {
            if (_data.playerheli.ContainsValue(heli.net.ID.Value))
            {
                string key = _data.playerheli.FirstOrDefault(x => x.Value == heli.net.ID.Value).Key;


                ulong result;
                ulong.TryParse(key, out result);
                BasePlayer player = BasePlayer.FindByID(result);


                if (player != null)
                    player.ChatMessage(lang.GetMessage("heli_destroyed", this, player.UserIDString));


                _data.playerheli.Remove(key);
            }
        }


        object OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
        {
            if (entity == null || info == null || entity.OwnerID == 0)
                return null;


            if (_data.playerheli.ContainsValue(entity.net.ID.Value))
                if (permission.UserHasPermission(entity.OwnerID.ToString(), _noDecay) && info.damageTypes.Has(Rust.DamageType.Decay))
                    return true;


            return null;
        }


        object CanMountEntity(BasePlayer player, BaseVehicleMountPoint entity)
        {
            if (player == null || entity == null)
                return null;


            var heli = entity.GetParentEntity() as ScrapTransportHelicopter;
            if (heli == null || heli is ScrapTransportHelicopter || heli.OwnerID == 0 || !IsPlayerOwned(heli)) return null;


            if (heli.OwnerID != player.userID)
            {
                if (player.Team != null && player.Team.members.Contains(heli.OwnerID))
                    return null;


                player.ChatMessage(lang.GetMessage("heli_canmount", this, player.UserIDString));
                return false;
            }
            return null;
        }


        void OnPlayerDisconnected(BasePlayer player)
        {
            // Temporary workaround for OnPlayerDisconnected not subscribing to Oxide issue.
            if (!_config.destroyOnDisconnect)
                return;


            if (player == null)
                return;


            ulong heliNetId;
            if (!_data.playerheli.TryGetValue(player.UserIDString, out heliNetId))
                return;


            var heli = BaseNetworkable.serverEntities.Find(new NetworkableId(heliNetId)) as ScrapTransportHelicopter;
            if (heli == null)
                return;


            NextTick(() =>
            {
                if (heli == null)
                    return;


                // Despawn ScrapTransportHelicopter when the owner disconnects
                // If mounted, we will despawn it later when all players dismount
                if (!heli.AnyMounted())
                    heli.Kill();
            });
        }


        void OnEntityDismounted(BaseVehicleSeat seat)
        {
            if (seat == null)
                return;


            var heli = seat.GetParentEntity() as ScrapTransportHelicopter;
            if (heli == null || heli.OwnerID == 0 || !IsPlayerOwned(heli) || heli.AnyMounted())
                return;


            // Despawn ScrapTransportHelicopter when fully dismounted, if the owner player has disconnected
            var ownerPlayer = BasePlayer.FindByID(heli.OwnerID);
            if (ownerPlayer == null || !ownerPlayer.IsConnected)
                heli.Kill();
        }


        void CanLootEntity(BasePlayer player, StorageContainer container)
        {
            if (container == null || !container.IsLocked())
                return;


            var heli = container.GetParentEntity() as ScrapTransportHelicopter;
            if (heli == null || !IsPlayerOwned(heli))
                return;


            if (permission.UserHasPermission(heli.OwnerID.ToString(), _noFuel))
                player.ChatMessage(lang.GetMessage("heli_unlimited_fuel", this, player.UserIDString));
        }


        #endregion


        #region Commands


        [ChatCommand("myheli")]
        private void SpawnCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, _Spawnheli))
            {
                player.ChatMessage(lang.GetMessage("heli_perm", this, player.UserIDString));
                return;
            }


            var heli = FindPlayerheli(player);
            if (heli != null)
            {
                if (_config.autoFetch && permission.UserHasPermission(player.UserIDString, _fetchheli))
                {
                    FetchInternal(player, heli);
                }
                else
                {
                    player.ChatMessage(lang.GetMessage("heli_current", this, player.UserIDString));
                }


                return;
            }


            if (SpawnWasBlocked(player))
                return;


            if (!VerifyOffCooldown(player, _config.spawnPermissionCooldowns, _config.defaultSpawnCooldown, _data.spawnCooldowns))
                return;


            Spawnhelicopter(player);
        }


        [ChatCommand("fheli")]
        private void FetchCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, _fetchheli))
            {
                player.ChatMessage(lang.GetMessage("heli_perm", this, player.UserIDString));
                return;
            }


            var heli = FindPlayerheli(player);
            if (heli == null)
            {
                player.ChatMessage(lang.GetMessage("heli_notcurrent", this, player.UserIDString));
                return;
            }


            FetchInternal(player, heli);
        }


        [ChatCommand("noheli")]
        private void DespawnCommand(BasePlayer player, string command, string[] args)
        {
            if (!permission.UserHasPermission(player.UserIDString, _noHeli))
            {
                player.ChatMessage(lang.GetMessage("heli_perm", this, player.UserIDString));
                return;
            }


            var heli = FindPlayerheli(player);
            if (heli == null)
            {
                player.ChatMessage(lang.GetMessage("heli_notcurrent", this, player.UserIDString));
                return;
            }


            if (heli.AnyMounted() && !_config.canDespawnWhileOccupied)
            {
                player.ChatMessage(lang.GetMessage("heli_mounted", this, player.UserIDString));
                return;
            }


            if (IsheliBeyondMaxDistance(player, heli))
            {
                player.ChatMessage(lang.GetMessage("heli_current_distance", this, player.UserIDString));
                return;
            }


            if (DespawnWasBlocked(player, heli))
                return;


            BaseNetworkable.serverEntities.Find(new NetworkableId(_data.playerheli[player.UserIDString]))?.Kill();
        }


        [ConsoleCommand("Spawnheli.give")]
        private void GiveheliConsole(ConsoleSystem.Arg arg)
        {
            if (arg.IsClientside || !arg.IsRcon)
                return;


            var args = arg.Args;
            if (args == null || args.Length == 0)
            {
                Puts("Syntax: Spawnheli.give <name or steamid>");
                return;
            }


            var player = BasePlayer.Find(args[0]);
            if (player == null)
            {
                PrintError($"No player found matching '{args[0]}'");
                return;
            }


            if (args.Length > 1)
            {
                float x, y, z;
                if (args.Length < 4 ||
                    !float.TryParse(args[1], out x) ||
                    !float.TryParse(args[2], out y) ||
                    !float.TryParse(args[3], out z))
                {
                    Puts($"Syntax: Spawnheli.give <name or steamid> <x> <y> <z>");
                    return;
                }


                GiveScrapTransportHelicopter (player, new Vector3(x, y, z), useCustomPosition: true);
            }
            else
            {
                GiveScrapTransportHelicopter (player);
            }
        }


        #endregion


        #region Helpers/Functions


        private bool VerifyOffCooldown(BasePlayer player, Dictionary<string, float> cooldownPerms, float defaultCooldown, Dictionary<string, DateTime> cooldownMap)
        {
            DateTime cooldownStart;
            if (!cooldownMap.TryGetValue(player.UserIDString, out cooldownStart) || permission.UserHasPermission(player.UserIDString, _noCooldown))
            {
                return true;
            }


            DateTime lastSpawned = cooldownMap[player.UserIDString];
            TimeSpan timeRemaining = CeilingTimeSpan(lastSpawned.AddSeconds(GetPlayerCooldownSeconds(player, cooldownPerms, defaultCooldown)) - DateTime.Now);
            if (timeRemaining.TotalSeconds <= 0)
            {
                cooldownMap.Remove(player.UserIDString);
                return true;
            }


            player.ChatMessage(string.Format(lang.GetMessage("heli_timeleft_new", this, player.UserIDString), timeRemaining.ToString("g")));
            return false;
        }


        private bool SpawnWasBlocked(BasePlayer player)
        {
            object hookResult = Interface.CallHook("OnMyheliSpawn", player);
            return hookResult is bool && (bool)hookResult == false;
        }


        private bool FetchWasBlocked(BasePlayer player, ScrapTransportHelicopter heli)
        {
            object hookResult = Interface.CallHook("OnMyheliFetch", player, heli);
            return hookResult is bool && (bool)hookResult == false;
        }


        private bool DespawnWasBlocked(BasePlayer player, ScrapTransportHelicopter heli)
        {
            object hookResult = Interface.CallHook("OnMyheliDespawn", player, heli);
            return hookResult is bool && (bool)hookResult == false;
        }


        private TimeSpan CeilingTimeSpan(TimeSpan timeSpan) =>
            new TimeSpan((long)Math.Ceiling(1.0 * timeSpan.Ticks / 10000000) * 10000000);


        private bool IsheliBeyondMaxDistance(BasePlayer player, ScrapTransportHelicopter heli) =>
            _config.noHeliDistance >= 0 && GetDistance(player, heli) > _config.noHeliDistance;


        private Vector3 GetFixedPositionForPlayer(BasePlayer player)
        {
            Vector3 forward = player.GetNetworkRotation() * Vector3.forward;
            forward.y = 0;
            return player.transform.position + forward.normalized * _config.fixedSpawnDistance + Vector3.up * 2f;
        }


        private Quaternion GetFixedRotationForPlayer(BasePlayer player) =>
            Quaternion.Euler(0, player.GetNetworkRotation().eulerAngles.y - _config.fixedSpawnRotationAngle, 0);


        private ScrapTransportHelicopter  FindPlayerheli(BasePlayer player)
        {
            ulong heliNetId;
            if (!_data.playerheli.TryGetValue(player.UserIDString, out heliNetId))
                return null;


            var heli = BaseNetworkable.serverEntities.Find(new NetworkableId(heliNetId)) as ScrapTransportHelicopter;


            // Fix a potential data file desync where the heli doesn't exist anymore
            // Desyncs should be rare but are not possible to 100% prevent
            // They can happen if the heli is destroyed while the plugin is unloaded
            // Or if someone edits the data file manually
            if (heli == null)
                _data.playerheli.Remove(player.UserIDString);


            return heli;
        }


        private void FetchInternal(BasePlayer player, ScrapTransportHelicopter heli)
        {
            if (!_config.canFetchBuildlingBlocked && player.IsBuildingBlocked())
            {
                player.ChatMessage(lang.GetMessage("heli_buildingblocked", this, player.UserIDString));
                return;
            }


            bool isMounted = heli.AnyMounted();
            if (isMounted && (!_config.canFetchWhileOccupied || player.GetMountedVehicle() == heli))
            {
                player.ChatMessage(lang.GetMessage("heli_mounted", this, player.UserIDString));
                return;
            }


            if (IsheliBeyondMaxDistance(player, heli))
            {
                player.ChatMessage(lang.GetMessage("heli_current_distance", this, player.UserIDString));
                return;
            }


            if (FetchWasBlocked(player, heli))
                return;


            if (!VerifyOffCooldown(player, _config.fetchPermissionCooldowns, _config.defaultFetchCooldown, _data.fetchCooldowns))
                return;


            if (isMounted)
            {
                // heli.DismountAllPlayers() doesn't work so we have to enumerate the mount points
                foreach (var mountPoint in heli.mountPoints)
                    mountPoint.mountable?.DismountAllPlayers();
            }


            if (_config.repairOnFetch)
            {
                heli.SetHealth(Math.Max(heli.Health(), _config.spawnHealth));
            }


            heli.rigidBody.velocity = Vector3.zero;
            heli.transform.SetPositionAndRotation(GetFixedPositionForPlayer(player), GetFixedRotationForPlayer(player));
            heli.UpdateNetworkGroup();
            heli.SendNetworkUpdateImmediate();


            if (!permission.UserHasPermission(player.UserIDString, _noCooldown))
            {
                _data.fetchCooldowns[player.UserIDString] = DateTime.Now;
            }
        }


        private void Spawnhelicopter(BasePlayer player)
        {
            if (!_config.canSpawnBuildingBlocked && player.IsBuildingBlocked())
            {
                player.ChatMessage(lang.GetMessage("heli_buildingblocked", this, player.UserIDString));
                return;
            }


            Vector3 position;


            if (_config.useFixedSpawnDistance)
            {
                position = GetFixedPositionForPlayer(player);
            }
            else
            {
                RaycastHit hit;
                if (!Physics.Raycast(player.eyes.HeadRay(), out hit, Mathf.Infinity,
                    LayerMask.GetMask("Construction", "Default", "Deployed", "Resource", "Terrain", "Water", "World")))
                {
                    player.ChatMessage(lang.GetMessage("heli_terrain", this, player.UserIDString));
                    return;
                }


                if (hit.distance > _config.maxSpawnDistance)
                {
                    player.ChatMessage(lang.GetMessage("heli_sdistance", this, player.UserIDString));
                    return;
                }


                position = hit.point + Vector3.up * 2f;
            }


            ScrapTransportHelicopter heli = GameManager.server.CreateEntity(_config.assetPrefab, position, GetFixedRotationForPlayer(player)) as ScrapTransportHelicopter;
            if (heli == null) return;


            heli.OwnerID = player.userID;
            heli.startHealth = _config.spawnHealth;
            heli.Spawn();


            // Credit Original MyScrapTransportHelicopter  Plugin
            if (permission.UserHasPermission(player.UserIDString, _noFuel))
                EnableUnlimitedFuel(heli);
            else
                AddInitialFuel(heli, player.UserIDString);


            _data.playerheli.Add(player.UserIDString, heli.net.ID.Value);


            if (!permission.UserHasPermission(player.UserIDString, _noCooldown))
            {
                _data.spawnCooldowns[player.UserIDString] = DateTime.Now;
            }
        }


        private void GiveScrapTransportHelicopter (BasePlayer player, Vector3 customPosition = default(Vector3), bool useCustomPosition = false)
        {
            if (FindPlayerheli(player) != null)
            {
                player.ChatMessage(lang.GetMessage("heli_current", this, player.UserIDString));
                return;
            }


            var position = useCustomPosition ? customPosition : GetFixedPositionForPlayer(player);
            var rotation = useCustomPosition ? Quaternion.identity : GetFixedRotationForPlayer(player);


            ScrapTransportHelicopter heli = GameManager.server.CreateEntity(_config.assetPrefab, position, GetFixedRotationForPlayer(player)) as ScrapTransportHelicopter;
            if (heli == null) return;


            heli.OwnerID = player.userID;
            heli.Spawn();


            _data.playerheli.Add(player.UserIDString, heli.net.ID.Value);


            if (permission.UserHasPermission(player.UserIDString, _noFuel))
                EnableUnlimitedFuel(heli);
            else
                AddInitialFuel(heli, player.UserIDString);
        }


        private float GetPlayerCooldownSeconds(BasePlayer player, Dictionary<string, float> cooldownPerms, float defaultCooldown)
        {
            var grantedCooldownPerms = cooldownPerms
                .Where(entry => permission.UserHasPermission(player.UserIDString, entry.Key));


            return grantedCooldownPerms.Any()
                ? grantedCooldownPerms.Min(entry => entry.Value)
                : defaultCooldown;
        }


        private void AddInitialFuel(ScrapTransportHelicopter ScrapTransportHelicopter, string userId)
        {
            var fuelAmount = GetPlayerAllowedFuel(userId);
            if (fuelAmount == 0)
                return;


            StorageContainer fuelContainer = ScrapTransportHelicopter.GetFuelSystem().GetFuelContainer();
            if (fuelAmount < 0)
            {
                // Value of -1 is documented to represent max stack size
                fuelAmount = fuelContainer.allowedItem.stackable;
            }
            fuelContainer.inventory.AddItem(fuelContainer.allowedItem, fuelAmount);
        }


        private void EnableUnlimitedFuel(ScrapTransportHelicopter ScrapTransportHelicopter)
        {
            var fuelSystem = ScrapTransportHelicopter.GetFuelSystem();
            fuelSystem.cachedHasFuel = true;
            fuelSystem.nextFuelCheckTime = float.MaxValue;
            fuelSystem.GetFuelContainer().SetFlag(BaseEntity.Flags.Locked, true);
        }


        private float GetDistance(BasePlayer player, ScrapTransportHelicopter heli)
        {
            float distance = Vector3.Distance(player.transform.position, heli.transform.position);
            return distance;
        }


        private bool IsPlayerOwned(ScrapTransportHelicopter heli)
        {
            if (heli != null && _data.playerheli.ContainsValue(heli.net.ID.Value))
                return true;


            return false;
        }


        private string GetFuelPermission(int fuelAmount) => String.Format(_permissionFuelFormat, fuelAmount);


        #endregion


        #region Data & Configuration


        private int GetPlayerAllowedFuel(string userIdString)
        {
            if (_config.fuelAmountsRequiringPermission == null || _config.fuelAmountsRequiringPermission.Length == 0)
                return _config.fuelAmount;


            for (var i = _config.fuelAmountsRequiringPermission.Length - 1; i >= 0; i--)
            {
                var fuelAmount = _config.fuelAmountsRequiringPermission[i];
                if (permission.UserHasPermission(userIdString, String.Format(_permissionFuelFormat, fuelAmount)))
                    return fuelAmount;
            }


            return _config.fuelAmount;
        }


        private SaveData LoadSaveData()
        {
            _data = Interface.Oxide.DataFileSystem.ReadObject<SaveData>(Name);
            if (_data == null)
            {
                PrintWarning($"Data file {Name}.json is invalid. Creating new data file.");
                _data = new SaveData();
                WriteSaveData();
            }
            return _data;
        }


        private void WriteSaveData() =>
            Interface.Oxide.DataFileSystem.WriteObject(Name, _data);


        class SaveData
        {
            [JsonProperty("playerheli")]
            public Dictionary<string, ulong> playerheli = new Dictionary<string, ulong>();


            [JsonProperty("spawnCooldowns")]
            public Dictionary<string, DateTime> spawnCooldowns = new Dictionary<string, DateTime>();


            [JsonProperty("cooldown")]
            private Dictionary<string, DateTime> deprecatedCooldown
            {
                set { spawnCooldowns = value; }
            }


            [JsonProperty("fetchCooldowns")]
            public Dictionary<string, DateTime> fetchCooldowns = new Dictionary<string, DateTime>();
        }


        class PluginConfig : SerializableConfiguration
        {
            [JsonProperty("AssetPrefab")]
            public string assetPrefab = "assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab";


            [JsonProperty("CanDespawnWhileOccupied")]
            public bool canDespawnWhileOccupied = false;


            [JsonProperty("CanFetchWhileOccupied")]
            public bool canFetchWhileOccupied = false;


            [JsonProperty("CanSpawnBuildingBlocked")]
            public bool canSpawnBuildingBlocked = false;


            [JsonProperty("CanFetchBuildingBlocked")]
            public bool canFetchBuildlingBlocked = true;


            [JsonProperty("AutoFetch")]
            public bool autoFetch = false;


            [JsonProperty("RepairOnFetch")]
            public bool repairOnFetch = false;


            [JsonProperty("FuelAmount")]
            public int fuelAmount = 0;


            [JsonProperty("FuelAmountsRequiringPermission")]
            public int[] fuelAmountsRequiringPermission = new int[0];


            [JsonProperty("MaxNoHeliDistance")]
            public float noHeliDistance = -1;


            [JsonProperty("MaxSpawnDistance")]
            public float maxSpawnDistance = 5f;


            [JsonProperty("UseFixedSpawnDistance")]
            public bool useFixedSpawnDistance = true;


            [JsonProperty("FixedSpawnDistance")]
            public float fixedSpawnDistance = 3;


            [JsonProperty("FixedSpawnRotationAngle")]
            public float fixedSpawnRotationAngle = 135;


            [JsonProperty("OwnerAndTeamCanMount")]
            public bool ownerOnly = false;


            [JsonProperty("DefaultSpawnCooldown")]
            public float defaultSpawnCooldown = 3600f;


            [JsonProperty("DefaultCooldown")]
            private float deprecatedDefaultSpawnCooldown
            {
                set { defaultSpawnCooldown = value; }
            }


            [JsonProperty("PermissionSpawnCooldowns", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, float> spawnPermissionCooldowns = new Dictionary<string, float>()
            {
                ["Spawnheli.tier1"] = 600f,
                ["Spawnheli.tier2"] = 300f,
                ["Spawnheli.tier3"] = 60f,
            };


            [JsonProperty("PermissionCooldowns")]
            private Dictionary<string, float> deprecatedSpawnPermissionCooldowns
            {
                set { spawnPermissionCooldowns = value; }
            }


            [JsonProperty("DefaultFetchCooldown")]
            public float defaultFetchCooldown = 0;


            [JsonProperty("PermissionFetchCooldowns", ObjectCreationHandling = ObjectCreationHandling.Replace)]
            public Dictionary<string, float> fetchPermissionCooldowns = new Dictionary<string, float>()
            {
                ["Spawnheli.fetch.tier1"] = 600f,
                ["Spawnheli.fetch.tier2"] = 300f,
                ["Spawnheli.fetch.tier3"] = 60f,
            };


            [JsonProperty("SpawnHealth")]
            public float spawnHealth = 750f;


            [JsonProperty("DestroyOnDisconnect")]
            public bool destroyOnDisconnect = false;
        }


        private PluginConfig GetDefaultConfig() => new PluginConfig();


        #endregion


        #region Localization


        protected override void LoadDefaultMessages()
        {
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["heli_destroyed"] = "Your ScrapTransportHelicopter has been destroyed!",
                ["heli_perm"] = "You do not have permission to use this command!",
                ["heli_current"] = "You already have a ScrapTransportHelicopter!",
                ["heli_notcurrent"] = "You do not have a ScrapTransportHelicopter!",
                ["heli_buildingblocked"] = "Нельзя вызывать в чужой зоне строительства!",
                ["heli_timeleft_new"] = "You have <color=red>{0}</color> until your cooldown ends",
                ["heli_sdistance"] = "You're trying to spawn the ScrapTransportHelicopter too far away!",
                ["heli_terrain"] = "Trying to spawn ScrapTransportHelicopter outside of terrain!",
                ["heli_mounted"] = "A player is currenty mounted on the ScrapTransportHelicopter!",
                ["heli_current_distance"] = "The ScrapTransportHelicopter  is too far!",
                ["heli_canmount"] = "You are not the owner of this ScrapTransportHelicopter or in the owner's team!",
                ["heli_unlimited_fuel"] = "Не нуждается в заправке!",
                ["heli_location_restricted"] = "Не можете быть вызвать здесь!",
            }, this, "en");
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["heli_destroyed"] = "Ваш Транспортный вертрлёт был уничтожен!",
                ["heli_perm"] = "У вас нет разрешения на использование этой команды!",
                ["heli_current"] = "У вас уже есть Транспортный вертрлёт!",
                ["heli_notcurrent"] = "У вас нет Транспортного вертрлёта!",
                ["heli_timeleft_new"] = "У вас есть <color=red>{0}</color>, пока ваше время восстановления не закончится.",
                ["heli_sdistance"] = "Вы пытаетесь вызвать Транспортный вертрлёт, но вы слишком далеко указываете!",
                ["heli_terrain"] = "Попытка вызвать Транспортный вертрлёт вне поверхности!",
                ["heli_mounted"] = "Игрок в данный момент сидит в Транспортном вертрлёте или вы слишком далеко!",
                ["heli_current_distance"] = "Транспортный вертрлёт слишком далеко!",
                ["heli_canmount"] = "Вы не являетесь владельцем этого Транспортного вертрлёта или не в команде владельца!"
            }, this, "ru");
            lang.RegisterMessages(new Dictionary<string, string>
            {
                ["heli_destroyed"] = "Ihr helikopter wurde zerstört!",
                ["heli_perm"] = "Du habe keine keine berechtigung diesen befehl zu verwenden!",
                ["heli_current"] = "Du hast bereits einen helikopter!",
                ["heli_notcurrent"] = "Du hast keine helikopter!",
                ["heli_timeleft_new"] = "Du hast <color=red>{0}</color>, bis ihre abklingzeit ende",
                ["heli_sdistance"] = "Du bist versuchen den helikopter zu weit weg zu spawnen!",
                ["heli_terrain"] = "Du versucht laichen einen helikopter außerhalb des geländes!",
                ["heli_mounted"] = "Ein Spieler ist gerade am helikopter montiert oder es ist zu weit!",
                ["heli_current_distance"] = "Der helikopter ist zu weit!",
                ["heli_rcon"] = "Dieser Befehl kann nur von RCON ausgeführt werden!",
                ["heli_canmount"] = "Sie sind nicht der Besitzer dieses ScrapTransportHelicopter s oder im Team des Besitzers!"
            }, this, "de");
        }


        #endregion


        #region Configuration Boilerplate


        internal class SerializableConfiguration
        {
            public string ToJson() => JsonConvert.SerializeObject(this);


            public Dictionary<string, object> ToDictionary() => JsonHelper.Deserialize(ToJson()) as Dictionary<string, object>;
        }


        internal static class JsonHelper
        {
            public static object Deserialize(string json) => ToObject(JToken.Parse(json));


            private static object ToObject(JToken token)
            {
                switch (token.Type)
                {
                    case JTokenType.Object:
                        return token.Children<JProperty>()
                                    .ToDictionary(prop => prop.Name,
                                                  prop => ToObject(prop.Value));


                    case JTokenType.Array:
                        return token.Select(ToObject).ToList();


                    default:
                        return ((JValue)token).Value;
                }
            }
        }


        private bool MaybeUpdateConfig(SerializableConfiguration config)
        {
            var currentWithDefaults = config.ToDictionary();
            var currentRaw = Config.ToDictionary(x => x.Key, x => x.Value);
            return MaybeUpdateConfigDict(currentWithDefaults, currentRaw);
        }


        private bool MaybeUpdateConfigDict(Dictionary<string, object> currentWithDefaults, Dictionary<string, object> currentRaw)
        {
            bool changed = false;


            foreach (var key in currentWithDefaults.Keys)
            {
                object currentRawValue;
                if (currentRaw.TryGetValue(key, out currentRawValue))
                {
                    var defaultDictValue = currentWithDefaults[key] as Dictionary<string, object>;
                    var currentDictValue = currentRawValue as Dictionary<string, object>;


                    if (defaultDictValue != null)
                    {
                        // Don't update nested keys since the cooldown tiers might be customized
                        if (currentDictValue == null)
                        {
                            currentRaw[key] = currentWithDefaults[key];
                            changed = true;
                        }
                    }
                }
                else
                {
                    currentRaw[key] = currentWithDefaults[key];
                    changed = true;
                }
            }


            return changed;
        }


        protected override void LoadDefaultConfig() => _config = GetDefaultConfig();


        protected override void LoadConfig()
        {
            base.LoadConfig();
            try
            {
                _config = Config.ReadObject<PluginConfig>();
                if (_config == null)
                {
                    throw new JsonException();
                }


                if (MaybeUpdateConfig(_config))
                {
                    PrintWarning("Configuration appears to be outdated; updating and saving");
                    SaveConfig();
                }
            }
            catch (Exception e)
            {
                PrintError(e.Message);
                PrintWarning($"Configuration file {Name}.json is invalid; using defaults");
                LoadDefaultConfig();
            }
        }


        protected override void SaveConfig()
        {
            Puts($"Configuration changes saved to {Name}.json");
            Config.WriteObject(_config, true);
        }


        #endregion
    }
}
 
Вы же понимаете, что вы мне скидываете куски своего КАСТОМНОГО кода и чтобы они заработали правильно у меня, мне нужно их логически соединить со своим, таким же, кастомным кодом. Но проблема вся заключается в том, что, я не обладаю такими обширными знаниями, чтобы все петли объединить в одну. Мне нужно, либо ваша сторона кода(полная), либо моя, допустим объединенная с вашим кодом, чтобы добиться нужного результата, а иначе, победы, лично мне, не видать в моей проблеме.
Давайте, поступим так, если у вас есть возможность и желание, помогите мне с моим плагином, я отправлю его следующим 1 сообщением целиком, чтобы было удобно с ним отработать вам.
Заранее, как всегда благодарю Вас за всю оказанную мне помощь!
это не кусок, а рабочий код. Создай отдельный плагин вставь туда этот класс , а посмотри работу, а далее уже интегрируй в свой код
 
  • Мне нравится
Реакции: DoKZaMmer
  • Мне нравится
Реакции: DoKZaMmer
По идее если взять плагин с юмод, и заменить Minicopter heli = GameManager.server.CreateEntity("assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", pos, new Quaternion(), true) as Minicopter;

На
ScrapTransportHelicopter heli = GameManager.server.CreateEntity("assets/content/vehicles/scrap heli carrier/scraptransporthelicopter.prefab", pos, new Quaternion(), true) as ScrapTransportHelicopter;

То все должно заработать, но это не точно.

Лучше делай плагин по этапно и с нуля

Сначала спавнить научись, далее удалять , добавлять доп опции (количества топливо в баке при спавне например) потом кд на использование команды добавь, разрешения,
 
  • Мне нравится
Реакции: DoKZaMmer
это не кусок, а рабочий код. Создай отдельный плагин вставь туда этот класс , а посмотри работу, а далее уже интегрируй в свой код
Я понимаю, что он рабочий код, даже на этот счёт, спорить не буду. Но, когда я его скрещиваю со своим, находя схожесть по общим параметрам, сервер начинается отрицать этот плагин, т.к он не понимает, что он от него требует, а просматривая, все схожести по ваше коду, с моим, я не вижу проблем, от которых сервер отказывается принимать плагин. В этом вся и проблема, что мне, увы и ах, не хватает таких глубоких познаний в этой сфере, собственно почему я и обратился на форум, чтобы помогли и указали на ошибки, чтобы в будущем я с таким не сталкивался....
 
Активность
Пока никто не печатает сообщение

Похожие темы