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

FREE HotAirDrops : 1.1.1 1.1.1

Нет прав для скачивания
C#:
using Facepunch.Extend;
using Oxide.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnityEngine;

namespace Oxide.Plugins
{
    [Info("HotAirDrops", "MBR", "1.1.1")]
    class HotAirDrops : RustPlugin
    {
        #region Constants

        private const int CRATE_UNTOUCHED = 69;
        private const int CRATE_LOOTED = 70;

        #endregion

        #region Hooks

        private void OnLootEntity(BasePlayer player, BaseEntity entity)
        {
            if (entity is HackableLockedCrate && entity.OwnerID == CRATE_UNTOUCHED)
            {
                Server.Broadcast("<size=18>The crate dropped by the <color=orange>hot air balloon</color> is now being <color=#FF7930>looted!</color></size>");
                entity.OwnerID = CRATE_LOOTED;
            }
        }

        private object CanSamSiteShoot(SamSite sam)
        {
            if (sam == null || sam.IsDestroyed || sam.currentTarget == null) return null;

            var balloon = sam.currentTarget as HotAirBalloon;
            if (balloon == null) return null;

            if (balloon.GetComponent<CustomHotAirBalloon>() != null) return false;

            return null;
        }

        #endregion

        #region Classes

        private class CustomCargoPlane : MonoBehaviour
        {
            private enum Progress
            {
                Vibing,
                LeftBank,
                LeftCircle,
                RightBank
            }

            private const float rotationRadius = 100f;
            private const float rotationSpeed = 40f;
            private const float bankValue = 10f;
            private readonly Vector3 rotationAxis = new Vector3(0f, 1f, 0f);
            private readonly float delta = rotationSpeed * Time.fixedDeltaTime;
            private readonly List<Progress> flightPlan = new List<Progress> { Progress.Vibing, Progress.LeftBank, Progress.LeftCircle, Progress.RightBank, Progress.Vibing };

            private float secondsTaken = 0f, secondsToTake = 0f;
            private float bankTimeToTake = 1f, bankTimeTaken = 0f;
            private float totalDegrees = 0f;

            private float bank
            {
                get
                {
                    return bankValue * (state == Progress.RightBank ? -1 : 1);
                }
            }

            private CargoPlane plane;
            private Progress state = Progress.Vibing;
            private bool startedCircling = false;

            private Vector3 startPos, endPos;
            private Vector3 rotationVector = Vector3.zero;

            public BoxStorage lootSource;

            private void Awake()
            {
                plane = GetComponent<CargoPlane>();
                plane.enabled = false;

                startPos = plane.transform.position;
                endPos = plane.endPos;
                startPos.y = 500f;
                endPos.y = 500f;

                secondsToTake = Vector3.Distance(startPos, endPos) / 50f;
                secondsToTake *= UnityEngine.Random.Range(0.95f, 1.05f);
                plane.transform.position = startPos;
                plane.transform.rotation = Quaternion.LookRotation(endPos - startPos);
            }

            private void FixedUpdate()
            {
                if (plane == null || plane.IsDestroyed) return;

                try
                {
                    TickBankProcess();

                    if (state == Progress.LeftCircle)
                    {
                        //drop the crate at half way through the circle
                        if (totalDegrees == 180) DropHAB(plane.transform.position, lootSource);

                        //exit circle
                        if (totalDegrees == 350 && state == Progress.LeftCircle)
                        {
                            state = Progress.RightBank;
                        }
                        
                        plane.transform.RotateAround(rotationVector, rotationAxis, -delta);
                        totalDegrees += delta;
                        return;
                    }

                    if (state == Progress.Vibing || state == Progress.LeftBank || state == Progress.RightBank)
                    {
                        secondsTaken += Time.deltaTime;
                        float single = Mathf.InverseLerp(0f, secondsToTake, secondsTaken);

                        plane.transform.position = Vector3.Lerp(startPos, endPos, single);
                        if (state == Progress.Vibing) plane.transform.rotation = Quaternion.LookRotation(endPos - startPos);

                        //start circling at half way
                        if (!startedCircling && single >= 0.5f)
                        {
                            startedCircling = true;
                            state = Progress.LeftBank;
                            //set the point around which the plane will circle
                            rotationVector = plane.transform.position + plane.transform.right * -rotationRadius;
                        }

                        if (single >= 1f) plane.Kill(BaseNetworkable.DestroyMode.None);
                    }
                }

                catch (Exception ex)
                {
                    Interface.Oxide.LogError(ex.ToString());
                    Interface.Oxide.LogWarning("FixedUpdate errored, calling DoDestroy()!");
                    GameObject.Destroy(this);
                }
            }

            private void TickBankProcess()
            {
                if (state != Progress.LeftBank && state != Progress.RightBank) return;

                bankTimeTaken += Time.deltaTime;
                float single = Mathf.InverseLerp(0f, bankTimeToTake, bankTimeTaken);
                plane.transform.Rotate(new Vector3(0f, 0f, bank), single);

                if (single == 1f)
                {
                    state = flightPlan[flightPlan.IndexOf(state) + 1];
                    bankTimeTaken = 0f;
                }
            }
        }

        private class CustomHotAirBalloon : MonoBehaviour
        {
            private HotAirBalloon HAB = null;
            private HackableLockedCrate HLC = null;

            public BoxStorage lootSource;

            private void Awake()
            {
                HAB = GetComponent<HotAirBalloon>();
                HLC = GetComponentInChildren<HackableLockedCrate>();

                HAB.fuelSystem.AdminAddFuel();
                HAB.inflationLevel = 1f;
                HAB.liftAmount = 485f;
                HAB.SetFlag(BaseEntity.Flags.On, true);
                HAB.SendNetworkUpdateImmediate();

                InvokeHandler.InvokeRepeating(this, LandCheck, 1f, 1f);

                HLC.transform.localPosition = new Vector3(0f, 0.45f, 0f);
                HLC.SendNetworkUpdate();
                HLC.GetComponent<Rigidbody>().isKinematic = true;
                HLC.GetComponent<Rigidbody>().detectCollisions = false;
                HLC.OwnerID = CRATE_UNTOUCHED;
                HLC.enableSaving = false;
                HLC.SetWasDropped();
                HLC.hackSeconds = HackableLockedCrate.requiredHackSeconds - 1f;
                HLC.inventory.capacity = 36;

                InvokeHandler.Invoke(this, () =>
                {
                    foreach (var item in HLC.inventory.itemList.ToList())
                    {
                        item.RemoveFromContainer();
                        item.RemoveFromWorld();
                    }

                    if (lootSource != null && lootSource.inventory.itemList.Count > 0)
                    {
                        for (int i = 0; i < lootSource.inventory.itemList.Count; i++)
                        {
                            var item = lootSource.inventory.itemList[i];
                            if (item != null) item.MoveToContainer(HLC.inventory);
                        }
                    }

                    InvokeHandler.Invoke(this, () =>
                    {
                        lootSource.KillMessage();
                    }, 1f);
                }, 1f);
            }

            private void LandCheck()
            {
                var ray = new Ray(transform.position + (Vector3.up * 0.5f), Vector3.down);

                if (Physics.Raycast(ray, 5f, 1084293377)) Drop();
            }

            public void Drop()
            {
                InvokeHandler.CancelInvoke(this, LandCheck);

                InvokeHandler.Invoke(this, () =>
                {
                    HAB.liftAmount = 1000f;
                    HAB.SetFlag(BaseEntity.Flags.On, true);
                    HAB.SendNetworkUpdateImmediate();

                    InvokeHandler.Invoke(this, () =>
                    {
                        if (HAB != null && !HAB.IsDestroyed) HAB.KillMessage();
                    }, 50f);
                }, 1f);
                
                HLC.SetParent(null, true, false);
                var y = Mathf.Max(HLC.transform.position.y - 2, TerrainMeta.HeightMap.GetHeight(HLC.transform.position));
                HLC.transform.position = new Vector3(HLC.transform.position.x, y, HLC.transform.position.z);
                HLC.SendNetworkUpdate();

                HLC.GetComponent<Rigidbody>().isKinematic = false;
                HLC.GetComponent<Rigidbody>().detectCollisions = true;
            }
        }

        #endregion

        #region Commands

        [ChatCommand("hotairdrop")]
        private void SpawnHotAirBaloonCMD(BasePlayer player, string command, string[] args)
        {
            if (!player.IsAdmin)
            {
                SendReply(player, "You don't have permission to use this command.");
                return;
            }

            var ent = GetLookAtEntity(player, 5f) as BoxStorage;
            if (ent == null)
            {
                SendReply(player, "You are not looking at a box!");
                return;
            }

            if (ent.inventory.itemList.Count < 1)
            {
                SendReply(player, "The box is empty!");
                return;
            }

            var plane = GameManager.server.CreateEntity("assets/prefabs/npc/cargo plane/cargo_plane.prefab", Vector3.zero) as CargoPlane;
            plane.Spawn();

            var component = plane.gameObject.AddComponent<CustomCargoPlane>();
            component.lootSource = ent;

            Server.Broadcast("<size=18>A <color=orange>hot air balloon</color> carrying <color=#FF7930>loot taken from cheaters</color> will be dropping soon! Be sure to watch the map for a moving locked crate.</size>");

            ent.transform.position = Vector3.zero;
            ent.SendNetworkUpdateImmediate();
        }

        #endregion

        #region Helpers

        private BaseEntity GetLookAtEntity(BasePlayer player, float maxDist = 250)
        {
            if (player == null || player.IsDead()) return null;
            RaycastHit hit;
            var currentRot = Quaternion.Euler(player?.serverInput?.current?.aimAngles ?? Vector3.zero) * Vector3.forward;
            var ray = new Ray((player?.eyes?.position ?? Vector3.zero), currentRot);
            if (Physics.Raycast(ray, out hit, maxDist))
            {
                var ent = hit.GetEntity() ?? null;
                if (ent != null && !(ent?.IsDestroyed ?? true)) return ent;
            }
            return null;
        }

        private static void DropHAB(Vector3 position, BoxStorage lootSource)
        {
            var HAB = "assets/prefabs/deployable/hot air balloon/hotairballoon.prefab";
            var HLC = "assets/prefabs/deployable/chinooklockedcrate/codelockedhackablecrate.prefab";

            try
            {
                var hotair = GameManager.server.CreateEntity(HAB, position) as HotAirBalloon;
                hotair.Spawn();

                var box = GameManager.server.CreateEntity(HLC, hotair.transform.position) as HackableLockedCrate;
                box.Spawn();

                box.SetParent(hotair, true, false);

                var component = hotair.gameObject.AddComponent<CustomHotAirBalloon>();
                component.lootSource = lootSource;
            }

            catch (Exception) { }
        }

        #endregion
    }
}

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