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

FREE Chute : 3.0.1 3.0.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6
using Rust;
using System;
using GameTips;
using UnityEngine;
using Newtonsoft.Json;
using Oxide.Core.Plugins;
using Oxide.Core.Configuration;
using Oxide.Game.Rust.Cui;
using System.Collections;
using System.Collections.Generic;
using Oxide.Core.Libraries.Covalence;
namespace Oxide.Plugins {
    [Info("Chute", "Colon Blow", "3.0.1")]
    class Chute : CovalencePlugin {
        // Added config options to block chute up if raid or combat blocked by NoEscape Plugin
        // Added config options for different cooldowns for chute and chuteup commands
        // Added config options for different VIP Coolodwns for chute and chuteup commands
#region Loadup
        [PluginReference]
        Plugin NoEscape;
        static Chute _instance;
        private const string permAllowed = "chute.allowed";
        private const string permAllowedUp = "chute.up.allowed";
        private const string permNoCooldown = "chute.nocooldown";
        private const string permVIPCooldown = "chute.vipcooldown";
        private static List<ulong> coolDownList = new List<ulong>();
        static int layerMask = 1 << (int)Rust.Layer.Water | 1 << (int)Rust.Layer.World | 1 << (int)Rust.Layer.Construction | 1 << (int)Rust.Layer.Debris | 1 << (int)Rust.Layer.Default | 1 << (int)Rust.Layer.Terrain | 1 << (int)Rust.Layer.Tree | 1 << (int)Rust.Layer.Vehicle_Large | 1 << (int)Rust.Layer.Deployed;
        private void Loaded() {
            _instance = this;
            LoadConfig();
            LoadMessages();
            permission.RegisterPermission(permAllowed, this);
            permission.RegisterPermission(permAllowedUp, this);
            permission.RegisterPermission(permNoCooldown, this);
            permission.RegisterPermission(permVIPCooldown, this);
        }
#endregion
#region Localization
        private void LoadMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                ["noperms"]
                = "You don't have permission to use this command.", ["commandnotfound"] = "Command was not found, please try again.", ["undercooldown"] = "Chute Cooldown Active, please wait : ", ["cooldownremoved"] = "Chute Cooldown removed !! ", ["onground"] = "You are too close to the ground to do that !!! ", ["alreadymounted"] = "You are already mounted !!", ["raidblocked"] = "Sorry, you are Raid Blocked, you cannot do that.", ["combatblocked"] = "Sorry, you are Combat Blocked, you cannot do that.", ["readytodismount"] = "<color=red>SAFTEY RELEASED !!!</color> PRESS <color=black>[JUMP KEY]</color> again to cut parachute away..warning you will Freefall !!!", ["usagemessage"] = "Use <color=black>[FWD, BACK, LEFT and RIGHT]</color> Keys to Speed UP, Slow Down and Turn\nPRESS <color=black>[JUMP KEY]</color> to cut away parachute and Free Fall !!"
            }
            , this);
        }
#endregion
#region Configuration
        private static PluginConfig config;
        private class PluginConfig {
            public ChuteSettings chuteSettings {
                get;
                set;
            }
            public class ChuteSettings {
                [JsonProperty(PropertyName = "Parachute - Speed - Max Forward speed allowed : ")]
                public float MaxParachuteFWDSpeed {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Parachute - Lift - Max up lift force allowed : ")]
                public float MaxParachteLift {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Drop Height - Altitude at which Chuteup moves player to : ")]
                public float ChuteDropHeight {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Cooldown - Enable Cooldown on using any Chute command ? ")]
                public bool UseCooldown {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Cooldown - Chute Command Cooldown Time (seconds) : ")]
                public float ChuteCoolDown {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Cooldown - Chute Up Command Cooldown Time (seconds) : ")]
                public float ChuteUpCoolDown {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Cooldown - VIP Chute Command Cooldown Time (Seconds) : ")]
                public float VIPChuteCoolDown {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Cooldown - VIP Chute Up Command Cooldown Time (Seconds) : ")]
                public float VIPChuteUpCoolDown {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "Global - Map size offset - Moves the spawn locations farther inland so Chute and Player dont spawn at edge of map : ")]
                public float GlobalMapOffset {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "NoEspace - Raid Blocked  - Prevent Chute Up command if players are Raid Blocked with No Escape Plugin ? ")]
                public bool BlockOnRaid {
                    get;
                    set;
                }
                [JsonProperty(PropertyName = "NoEspace - Combat Blocked  - Prevent Chute Up command if players are Combat Blocked with No Escape Plugin ? ")]
                public bool BlockOnCombat {
                    get;
                    set;
                }
            }
            public static PluginConfig DefaultConfig() => new PluginConfig() {
                chuteSettings = new PluginConfig.ChuteSettings {
                    MaxParachuteFWDSpeed = 15f, MaxParachteLift = 15f, ChuteDropHeight = 500f, UseCooldown = true, ChuteCoolDown = 600f, ChuteUpCoolDown = 1000f, VIPChuteCoolDown = 300f, VIPChuteUpCoolDown = 500f, GlobalMapOffset = 500f, BlockOnRaid = false, BlockOnCombat = false,
                }
            }
            ;
        }
        protected override void LoadDefaultConfig() {
            PrintWarning("New configuration file created!!");
            config = PluginConfig.DefaultConfig();
        }
        protected override void LoadConfig() {
            base.LoadConfig();
            config = Config.ReadObject<PluginConfig>();
            SaveConfig();
        }
        protected override void SaveConfig() {
            Config.WriteObject(config);
        }
#endregion
#region Commands
        [Command("Chute")]
        private void cmdChute(IPlayer iPlayer, string command, string[] args) {
            var player = iPlayer.Object as BasePlayer;
            if (player && permission.UserHasPermission(player.UserIDString, permAllowed)) {
                if (player.isMounted) {
                    iPlayer.Message(lang.GetMessage("alreadymounted", this, iPlayer.Id));
                    return;
                }
                if (PlayerOnGround(player)) return;
                ServerMgr.Instance.StartCoroutine(ChuteProcessing(player, false));
                return;
            }
            else player.IPlayer.Message(lang.GetMessage("noperms", this, player.IPlayer.Id));
        }
        [Command("Chuteup")]
        private void cmdChuteUp(IPlayer iPlayer, string command, string[] args) {
            var player = iPlayer.Object as BasePlayer;
            if (player && permission.UserHasPermission(player.UserIDString, permAllowedUp)) {
                if (player.isMounted) {
                    iPlayer.Message(lang.GetMessage("alreadymounted", this, iPlayer.Id));
                    return;
                }
                if (IsRaidBlocked(player) || IsCombatBlocked(player)) return;
                ServerMgr.Instance.StartCoroutine(ChuteProcessing(player, true));
                return;
            }
            else player.IPlayer.Message(lang.GetMessage("noperms", this, player.IPlayer.Id));
        }
#endregion
#region Rust Hooks
        private bool PlayerOnGround(BasePlayer player) {
            if (Physics.Raycast(new Ray(player.transform.position, Vector3.down), 3f, layerMask)) {
                player.IPlayer.Message(lang.GetMessage("onground", this, player.IPlayer.Id));
                return true;
            }
            return false;
        }
        private object CanDismountEntity(BasePlayer player, BaseMountable entity) {
            if (player == null || entity == null) return null;
            var isParachuting = entity.GetComponentInParent<ParachuteEntity>();
            if (isParachuting && !isParachuting.wantsDismount) return false;
            return null;
        }
#endregion
#region Methods
        private bool IsRaidBlocked(BasePlayer player) {
            if (NoEscape == null) return false;
            if (!config.chuteSettings.BlockOnRaid) return false;
            bool success = Convert.ToBoolean(NoEscape?.Call("IsRaidBlocked", player));
            if (success) player.IPlayer.Message(lang.GetMessage("raidblocked", this, player.IPlayer.Id));
            return success;
        }
        private bool IsCombatBlocked(BasePlayer player) {
            if (NoEscape == null) return false;
            if (!config.chuteSettings.BlockOnCombat) return false;
            bool success = Convert.ToBoolean(NoEscape?.Call("IsCombatBlocked", player));
            if (success) player.IPlayer.Message(lang.GetMessage("combatblocked", this, player.IPlayer.Id));
            return success;
        }
        private Vector3 FindRandomLocation() {
            Vector3 spawnpoint = new Vector3();
            float spawnline = ((ConVar.Server.worldsize) / 2) - config.chuteSettings.GlobalMapOffset;
            float yrandom = UnityEngine.Random.Range(config.chuteSettings.ChuteDropHeight * 0.75f, config.chuteSettings.ChuteDropHeight * 1.25f);
            spawnpoint = new Vector3(UnityEngine.Random.Range(-spawnline, spawnline), yrandom, UnityEngine.Random.Range(-spawnline, spawnline));
            return spawnpoint;
        }
        private IEnumerator ChuteProcessing(BasePlayer player, bool isRandom) {
            if (!permission.UserHasPermission(player.UserIDString, permNoCooldown)) {
                if (config.chuteSettings.UseCooldown) {
                    if (coolDownList.Contains(player.userID)) {
                        var timeLeft = config.chuteSettings.ChuteCoolDown;
                        if (isRandom) timeLeft = config.chuteSettings.ChuteUpCoolDown;
                        if (permission.UserHasPermission(player.UserIDString, permVIPCooldown)) {
                            timeLeft = config.chuteSettings.VIPChuteCoolDown;
                            if (isRandom) timeLeft = config.chuteSettings.VIPChuteUpCoolDown;
                        }
                        var hasTimer1 = player.GetComponent<CooldownTimer>();
                        if (hasTimer1) {
                            timeLeft = timeLeft - (hasTimer1.cooldownTimer / 15);
                        }
                        player.IPlayer.Message(lang.GetMessage("undercooldown", this, player.IPlayer.Id) + $" {timeLeft.ToString("F0")} Seconds Left.");
                        yield break;
                    }
                    coolDownList.Add(player.userID);
                    var hasTimer = player.GetComponent<CooldownTimer>();
                    if (hasTimer) {
                        hasTimer.OnDestroy();
                    }
                    ;
                    var addTimer = player.gameObject.AddComponent<CooldownTimer>();
                    addTimer.EnableTimer(isRandom);
                }
            }
            if (!isRandom) {
                OpenParachute(player);
                yield break;
            }
            RespawnAtRandom(player);
            yield return new WaitForEndOfFrame();
        }
        private void RespawnAtRandom(BasePlayer player) {
            if (player == null) return;
            Vector3 respawnpos = new Vector3(0f, config.chuteSettings.ChuteDropHeight, 0f);
            respawnpos = FindRandomLocation();
            MovePlayerToPosition(player, respawnpos, Quaternion.identity);
            OpenParachute(player);
        }
        private void MovePlayerToPosition(BasePlayer player, Vector3 position, Quaternion rotation) {
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Wounded, false);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Unused2, false);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.Unused1, false);
            player.SetPlayerFlag(BasePlayer.PlayerFlags.ReceivingSnapshot, true);
            player.transform.position = (position);
            player.transform.rotation = (rotation);
            player.StopWounded();
            player.StopSpectating();
            player.UpdateNetworkGroup();
            player.SendNetworkUpdateImmediate(false);
            player.ClearEntityQueue(null);
            player.SendFullSnapshot();
        }
        private static void DestroyAll<T>() {
            var objects = GameObject.FindObjectsOfType(typeof(T));
            if (objects != null) foreach (var gameObj in objects) GameObject.Destroy(gameObj);
        }
        private void SendInfoMessage(BasePlayer player, string message, float time) {
            player?.SendConsoleCommand("gametip.showgametip", message);
            timer.Once(time, () => player?.SendConsoleCommand("gametip.hidegametip"));
        }
        private void Unload() {
            coolDownList.Clear();
            DestroyAll<ParachuteEntity>();
            DestroyAll<CooldownTimer>();
        }
#endregion
#region API
        private void ExternalAddPlayerChute(BasePlayer player, bool isRandom = false) {
            ServerMgr.Instance.StartCoroutine(ChuteProcessing(player, isRandom));
        }
#endregion
#region Add Parachute
        public void OpenParachute(BasePlayer player) {
            if (player == null) return;
            var getParent = player.GetParentEntity();
            if (getParent != null) {
                float fwdVel = 1f;
                var hasRigid = getParent.GetComponentInParent<Rigidbody>();
                if (hasRigid) fwdVel = hasRigid.velocity.magnitude;
                AttachParachuteEntity(player, fwdVel);
            }
            else AttachParachuteEntity(player);
        }
        private void AttachParachuteEntity(BasePlayer player, float fwdVel = 1f) {
            Vector3 position = player.transform.position;
            var rotation = Quaternion.Euler(new Vector3(0f, player.GetNetworkRotation().eulerAngles.y, 0f));
            DroppedItem chutePack = new DroppedItem();
            chutePack = ItemManager.CreateByItemID(476066818, 1, 0).Drop(position, Vector3.zero, rotation).GetComponent<DroppedItem>();
            chutePack.allowPickup = false;
            chutePack.CancelInvoke((Action)Delegate.CreateDelegate(typeof(Action), chutePack, "IdleDestroy"));
            var addParachutePack = chutePack.gameObject.AddComponent<ParachuteEntity>();
            addParachutePack.fwdForce = fwdVel;
            addParachutePack.SetPlayer(player);
            addParachutePack.SetInput(player.serverInput);
        }
#endregion
#region Parachute Entity
        public class ParachuteEntity : MonoBehaviour {
            Chute _instance = new Chute();
            private DroppedItem worldItem;
            private Rigidbody myRigidbody;
            private BaseEntity chair;
            private BaseMountable chairMount;
            private BaseEntity parachute;
            private BasePlayer player;
            private InputState input;
            public float fwdForce = 5f;
            public float upForce = -10f;
            private float counter = 0f;
            private bool enabled = false;
            public bool wantsDismount = false;
            private bool forceDismount = false;
            private void Awake() {
                worldItem = GetComponent<DroppedItem>();
                if (worldItem == null) {
                    OnDestroy();
                    return;
                }
                myRigidbody = worldItem.GetComponent<Rigidbody>();
                if (myRigidbody == null) {
                    OnDestroy();
                    return;
                }
                parachute = GameManager.server.CreateEntity("assets/prefabs/misc/parachute/parachute.prefab", new Vector3(), new Quaternion(), false);
                parachute.enableSaving = true;
                parachute.SetParent(worldItem, 0, false, false);
                parachute?.Spawn();
                parachute.transform.localEulerAngles += new Vector3(0, 0, 0);
                parachute.transform.localPosition += new Vector3(0f, 1.3f, -0.1f);
                string chairprefab = "assets/bundled/prefabs/static/chair.invisible.static.prefab";
                chair = GameManager.server.CreateEntity(chairprefab, new Vector3(), new Quaternion(), false);
                chair.enableSaving = true;
                chair.GetComponent<BaseMountable>().isMobile = true;
                chair.Spawn();
                chair.transform.localEulerAngles += new Vector3(0, 0, 0);
                chair.transform.localPosition += new Vector3(0f, -1f, 0f);
                chair.SetParent(parachute, 0, false, false);
                chair.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
                chair.UpdateNetworkGroup();
                chairMount = chair.GetComponent<BaseMountable>();
                if (chairMount == null) {
                    OnDestroy();
                    return;
                }
                enabled = false;
            }
            private void OnCollisionEnter(Collision collision) {
                if (!enabled) return;
                if ((1 << (collision.gameObject.layer & 31) & 1084293393) > 0) {
                    this.OnDestroy();
                }
            }
            public void SetPlayer(BasePlayer player) {
                this.player = player;
                chair.GetComponent<BaseMountable>().MountPlayer(player);
                enabled = true;
                SendInfoMessage(player, _instance.lang.GetMessage("usagemessage", _instance, player.IPlayer.Id), 12f);
            }
            private void SendInfoMessage(BasePlayer player, string message, float time) {
                player?.SendConsoleCommand("gametip.showgametip", message);
                _instance.timer.Once(time, () => player?.SendConsoleCommand("gametip.hidegametip"));
            }
            public void SetInput(InputState input) {
                this.input = input;
            }
            private void FixedUpdate() {
                if (!enabled) return;
                if (chair == null || player == null || forceDismount || !chairMount._mounted) {
                    OnDestroy();
                    return;
                }
                var currentPlayerPos = player.transform.position;
                var currentPos = myRigidbody.transform.position;
                var getRotAngles = myRigidbody.transform.rotation.eulerAngles;
#region Collision Checks
                if (player != null && player.IsHeadUnderwater()) {
                    this.OnDestroy();
                    return;
                }
#endregion
#region Check Player Input
                if (input.WasJustPressed(BUTTON.JUMP)) {
                    if (wantsDismount) {
                        forceDismount = true;
                        OnDestroy();
                        return;
                    }
                    ;
                    SendInfoMessage(player, _instance.lang.GetMessage("readytodismount", _instance, player.IPlayer.Id), 8f);
                    wantsDismount = true;
                }
                // Check player input and adjust rotation accordingly
                if (input.IsDown(BUTTON.FORWARD) || input.IsDown(BUTTON.BACKWARD)) {
                    float direction = input.IsDown(BUTTON.FORWARD) ? 1f : -1f;
                    float newRotation = getRotAngles.x + direction;
                    bool isValidRotation = newRotation > 320f || newRotation < 40f;
                    float adjustment = isValidRotation ? newRotation : worldItem.transform.rotation.eulerAngles.x;
                    myRigidbody.transform.rotation = Quaternion.Euler(adjustment, myRigidbody.transform.rotation.eulerAngles.y, myRigidbody.transform.rotation.eulerAngles.z);
                }
                if (input.IsDown(BUTTON.RIGHT) || input.IsDown(BUTTON.LEFT)) {
                    float direction = input.IsDown(BUTTON.RIGHT) ? 1f : -1f;
                    myRigidbody.AddTorque(Vector3.up * direction, ForceMode.Acceleration);
                }
#endregion
#region Rotation Angle Checks
                float deltaForce = (1f + fwdForce / 10f) * Time.deltaTime;
                // If facing down, speed up and less lift, else if back slow down and more lift if fast enough
                if (getRotAngles.x == 0f) {
                    //...}
                    // if parachute is angled down in front, increase fwdForce and reduce upForce
                    else if (getRotAngles.x > 0f && getRotAngles.x < 180f) {
                        fwdForce = Mathf.MoveTowards(fwdForce, config.chuteSettings.MaxParachuteFWDSpeed, deltaForce);
                        upForce = Mathf.MoveTowards(upForce, -20f, deltaForce);
                    }
                    else if (getRotAngles.x == 180f) {
                        //...}
                        // if parachute is angled back
                        else if (getRotAngles.x > 180f && getRotAngles.x <= 379f) {
                            // If leaning back and going slow, slow fwd speed and reduce lift
                            if (fwdForce > 7f) {
                                fwdForce = Mathf.MoveTowards(fwdForce, -1f, 2f * Time.deltaTime);
                                upForce = Mathf.MoveTowards(upForce, 10f, 10f * Time.deltaTime);
                            }
                            else {
                                fwdForce = Mathf.MoveTowards(fwdForce, -1f, 3f * Time.deltaTime);
                                upForce = Mathf.MoveTowards(upForce, -10f, 4f * Time.deltaTime);
                            }
                        }
#endregion
#region Apply Forces
                        // Apply forward force
                        myRigidbody.AddForce(this.transform.forward * fwdForce, ForceMode.Acceleration);
                        // Apply damping force if there is any velocity
                        if (myRigidbody.velocity.magnitude != 0f) {
                            myRigidbody.AddForce(-myRigidbody.velocity.normalized * 5f, ForceMode.Acceleration);
                        }
                        // Apply upward impulse if downward velocity exceeds upward force
                        if (myRigidbody.velocity.y < upForce) {
                            myRigidbody.AddForce(Vector3.up * (upForce - myRigidbody.velocity.y), ForceMode.Impulse);
                        }
#endregion
#region Rotation Resistance
                        //Rotation Reistance Force
                        if (myRigidbody.angularVelocity.y != 0f) {
                            myRigidbody.AddTorque(new Vector3(0f, -myRigidbody.angularVelocity.y, 0f) * 1f, ForceMode.Acceleration);
                            myRigidbody.transform.rotation = Quaternion.Euler(myRigidbody.transform.rotation.eulerAngles.x, myRigidbody.transform.rotation.eulerAngles.y, -myRigidbody.angularVelocity.y * 50f);
                        }
#endregion
                        worldItem.transform.hasChanged = true;
                        worldItem.SendNetworkUpdateImmediate();
                        worldItem.UpdateNetworkGroup();
                        player.transform.hasChanged = true;
                        player.SendNetworkUpdateImmediate(false);
                        player.UpdateNetworkGroup();
                    }
                    public void Release() {
                        enabled = false;
                        if (chair != null && chair.GetComponent<BaseMountable>().IsMounted()) chair.GetComponent<BaseMountable>().DismountPlayer(player, false);
                        if (player != null && player.isMounted) player.DismountObject();
                        if (!chair.IsDestroyed) chair.Kill();
                        if (!parachute.IsDestroyed) parachute.Kill();
                        if (!worldItem.IsDestroyed) worldItem.Kill();
                        UnityEngine.GameObject.Destroy(this.gameObject);
                    }
                    public void OnDestroy() {
                        player = null;
                        Release();
                        GameObject.Destroy(this);
                    }
                }
#endregion
#region Chute Cooldown Timer
                public class CooldownTimer : MonoBehaviour {
                    private BasePlayer player;
                    public float cooldownTimer;
                    public float waitTime;
                    private bool enabled;
                    private void Awake() {
                        player = GetComponent<BasePlayer>();
                        if (player == null) {
                            OnDestroy();
                            return;
                        }
                        cooldownTimer = 0f;
                        waitTime = config.chuteSettings.ChuteCoolDown;
                        enabled = false;
                    }
                    public void EnableTimer(bool isChuteUp) {
                        if (!_instance.permission.UserHasPermission(player.UserIDString, permVIPCooldown)) {
                            waitTime = config.chuteSettings.ChuteCoolDown;
                            if (isChuteUp) waitTime = config.chuteSettings.ChuteUpCoolDown;
                        }
                        else {
                            waitTime = config.chuteSettings.VIPChuteCoolDown;
                            if (isChuteUp) waitTime = config.chuteSettings.VIPChuteUpCoolDown;
                        }
                        enabled = true;
                    }
                    private void SendInfoMessage(BasePlayer player, string message, float time) {
                        player?.SendConsoleCommand("gametip.showgametip", message);
                        _instance.timer.Once(time, () => player?.SendConsoleCommand("gametip.hidegametip"));
                    }
                    private void FixedUpdate() {
                        if (!enabled) return;
                        if (cooldownTimer >= waitTime * 15f) {
                            coolDownList.Remove(player.userID);
                            SendInfoMessage(player, _instance.lang.GetMessage("cooldownremoved", _instance, player.IPlayer.Id), 4f);
                            OnDestroy();
                        }
                        cooldownTimer++;
                    }
                    public void OnDestroy() {
                        GameObject.Destroy(this);
                    }
                }
#endregion
            }
        }

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