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

FREE Elevators : 1.0.1 1.0.1

Нет прав для скачивания
C#:
// Все права принадлежат дискорд сообществу https://discord.gg/VgNHPpNrz6

using System.Collections.Generic;
using System;
using System.Reflection;
using System.Data;
using UnityEngine;
using Oxide.Core;
using Oxide.Core.Configuration;
using Oxide.Core.Logging;
using Oxide.Core.Plugins;
using Rust;

namespace Oxide.Plugins
{
    [Info("Elevators", "Reneb", "1.0.1")]
    class Elevators : RustPlugin
    {
        [PluginReference]
        Plugin Waypoints;

        private static FieldInfo serverinput;
        StoredData storedData;
        static Hash<string, ElevatorInfo> elevators = new Hash<string, ElevatorInfo>();
        static Dictionary<string, string> nameToBlockPrefab = new Dictionary<string, string>();
        static List<Elevator> spawnedElevators = new List<Elevator>();
        static List<BaseCombatEntity> protectedBlock = new List<BaseCombatEntity>();
        public DamageTypeList emptyDamageType;
        // CACHED
        object closestEnt;
        Vector3 closestHitpoint;
        Quaternion currentRot;

        class StoredData
        {
            public HashSet<ElevatorInfo> Elevators = new HashSet<ElevatorInfo>();

            public StoredData()
            {
            }
        }
        void SaveData()
        {
            Interface.GetMod().DataFileSystem.WriteObject("Elevators", storedData);
        }
        void LoadData()
        {
            elevators.Clear();
            try
            {
                storedData = Interface.GetMod().DataFileSystem.ReadObject<StoredData>("Elevators");
            }
            catch
            {
                storedData = new StoredData();
            }
            foreach (var elevator in storedData.Elevators)
                elevators[elevator.Name] = elevator;
        }
        public class ElevatorInfo
        {
            public string Name;
            public string PrefabName;
            public string WaypointsName;
            public string rx;
            public string ry;
            public string rz;
            public string rw;
            public string Grade;

            public ElevatorInfo()
            {

            }
            public ElevatorInfo(BuildingBlock block, string name, string waypoints)
            {
                rx = block.transform.rotation.x.ToString();
                ry = block.transform.rotation.y.ToString();
                rz = block.transform.rotation.z.ToString();
                rw = block.transform.rotation.w.ToString();
                Grade = GradeToNum(block.grade).ToString();
                this.Name = name;
                this.WaypointsName = waypoints;
                this.PrefabName = block.blockDefinition.fullName;
            }
        }
        ////////////////////////////////////////////////////// 
        ///  class WaypointInfo
        ///  Waypoint information, position & speed
        ///  public => will be saved in the data file
        ///  non public => won't be saved in the data file
        //////////////////////////////////////////////////////
        public class WaypointInfo
        {
            public string x;
            public string y;
            public string z;
            public string s;
            Vector3 position;
            float speed;

            public WaypointInfo(Vector3 position, float speed)
            {
                x = position.x.ToString();
                y = position.y.ToString();
                z = position.z.ToString();
                s = speed.ToString();

                this.position = position;
                this.speed = speed;
            }

            public Vector3 GetPosition()
            {
                if (position == Vector3.zero)
                    position = new Vector3(float.Parse(x), float.Parse(y), float.Parse(z));
                return position;
            }
            public float GetSpeed()
            {
                speed = Convert.ToSingle(s);
                return speed;
            }
        }
        /////////////////////////////////////////////////////
        ///  GetGrade(int lvl)
        ///  Convert grade number written by the players into the BuildingGrade.Enum used by rust
        /////////////////////////////////////////////////////
        static BuildingGrade.Enum NumToGrade(int lvl)
        {
            if (lvl == 0)
                return BuildingGrade.Enum.Twigs;
            else if (lvl == 1)
                return BuildingGrade.Enum.Wood;
            else if (lvl == 2)
                return BuildingGrade.Enum.Stone;
            else if (lvl == 3)
                return BuildingGrade.Enum.Metal;
            return BuildingGrade.Enum.TopTier;
        }
        static int GradeToNum(BuildingGrade.Enum lvl)
        {
            if (lvl == BuildingGrade.Enum.Twigs)
                return 0;
            else if (lvl == BuildingGrade.Enum.Wood)
                return 1;
            else if (lvl == BuildingGrade.Enum.Stone)
                return 2;
            else if (lvl == BuildingGrade.Enum.Metal)
                return 3;
            return 4;
        }

        public class Elevator : MonoBehaviour
        {
            public ElevatorInfo info;
            public List<WaypointInfo> waypoints;
            public TriggerBase trigger;
            public BuildingBlock block;
            public UnityEngine.Quaternion rotation;


            public Vector3 StartPos = new Vector3(0f, 0f, 0f);
            public Vector3 EndPos = new Vector3(0f, 0f, 0f);
            public Vector3 nextPos = new Vector3(0f, 0f, 0f);
            public float waypointDone = 0f;
            public float secondsTaken = 0f;
            public float secondsToTake = 0f;
            public float speed = 4f;
            public int currentWaypoint = 0;

            public List<BaseEntity> collidingPlayers = new List<BaseEntity>();

            public Elevator()
            {

            }

            public void SetInfo(ElevatorInfo info)
            {
               
                this.info = info;
                var cwaypoints = Interface.CallHook("GetWaypointsList", this.info.WaypointsName);
                if (cwaypoints == null)
                {
                    Debug.Log(string.Format("{0} was destroyed, informations are invalid.Did you set waypoints? or a PrefabName?", info.Name));
                    GameObject.Destroy(this);
                    return;
                }
                this.waypoints = new List<WaypointInfo>();
                foreach (var cwaypoint in (List<object>)cwaypoints)
                {
                    foreach (KeyValuePair<Vector3, float> pair in (Dictionary<Vector3,float>)cwaypoint)
                    {
                        this.waypoints.Add(new WaypointInfo(pair.Key, pair.Value));
                    }
                }
                if (this.waypoints.Count < 2)
                {
                    Debug.Log(string.Format("{0} waypoints were detected for {1}.Needs at least 2 waypoints.Destroying.", this.waypoints.Count.ToString(), info.Name));
                    GameObject.Destroy(this);
                    return;
                }
                this.rotation = new UnityEngine.Quaternion(Convert.ToSingle(info.rx), Convert.ToSingle(info.ry), Convert.ToSingle(info.rz), Convert.ToSingle(info.rw));
                this.block = CreateBuildingBlock(this.info.PrefabName, this.waypoints[0].GetPosition(), this.rotation, Convert.ToInt32(this.info.Grade));
                if(this.block == null)
                {
                    Debug.Log(string.Format("Something went wrong, couldn't create the BuildingBlock for {0}", info.Name));
                    GameObject.Destroy(this);
                    return;
                }
                protectedBlock.Add(this.block.GetComponent<BaseCombatEntity>());
                trigger = block.GetComponentInChildren<MeshCollider>().gameObject.AddComponent<TriggerBase>();
                trigger.gameObject.name = "Elevator";
                var newlayermask = new UnityEngine.LayerMask();
                newlayermask.value = 133120;   
                trigger.interestLayers = newlayermask;
                trigger.gameObject.layer = UnityEngine.LayerMask.NameToLayer("Trigger");
                spawnedElevators.Add(this);
            }
            void Awake()
            {
                enabled = false;
            } 
            void OnDestroy()
            {
                if (this.block != null)
                {
                    protectedBlock.Remove(this.block.GetComponent<BaseCombatEntity>());
                    this.block.KillMessage();
                }
                if (this.trigger != null) GameObject.Destroy(this.trigger);
            } 
            void FixedUpdate()
            {
                if (secondsTaken == 0f) GetNextPath();
                if (!enabled) return;
                if (StartPos != EndPos) Execute_Move();
                if (waypointDone >= 1f) secondsTaken = 0f;
            }
            void Execute_Move()
            {
                secondsTaken += Time.deltaTime;
                waypointDone = Mathf.InverseLerp(0f, secondsToTake, secondsTaken);
                nextPos = Vector3.Lerp(StartPos, EndPos, waypointDone);
                block.transform.position = nextPos;
                block.SendNetworkUpdate(BasePlayer.NetworkQueue.UpdateDistance);
            }
            void GetNextPath()
            {
                if (currentWaypoint + 1 >= waypoints.Count)
                    currentWaypoint = -1;
                currentWaypoint++;
                if(currentWaypoint == 1 && collidingPlayers.Count==0)
                {
                    currentWaypoint = 0;
                    enabled = false;
                    return;
                }
                SetMovementPoint(block.transform.position, waypoints[currentWaypoint].GetPosition(), waypoints[currentWaypoint].GetSpeed());
                if (block.transform.position == waypoints[currentWaypoint].GetPosition()) { DeactivateMovement(); Invoke("ActivateMovement", waypoints[currentWaypoint].GetSpeed()); return; }
            }
            public void SetMovementPoint(Vector3 startpos, Vector3 endpos, float s)
            { 
                StartPos = startpos;
                EndPos = endpos;
                if (StartPos != EndPos)
                    secondsToTake = Vector3.Distance(EndPos, StartPos) / s;
                secondsTaken = 0f;
                waypointDone = 0f;
            }  
            public void ActivateMovement()
            {
                enabled = true;
            }
            public void DeactivateMovement()
            {
               enabled = false;
            }
        }
        void OnEntityEnter(TriggerBase triggerbase, BaseEntity entity)
        {
            if (triggerbase == null || entity == null) return;
            if (triggerbase.gameObject.name != "Elevator") return;
            foreach (Elevator ele in spawnedElevators)
            {
                if (ele.trigger == triggerbase)
                {
                    if (!ele.collidingPlayers.Contains(entity))
                        ele.collidingPlayers.Add(entity);
                    ele.ActivateMovement();
                } 
            }
        }
        void OnEntityLeave(TriggerBase triggerbase, BaseEntity entity)
        {
            if (triggerbase == null || entity == null) return;
            if (triggerbase.gameObject.name != "Elevator") return;
            foreach (Elevator ele in spawnedElevators)
            {
                if (ele.trigger == triggerbase)
                {
                    if (ele.collidingPlayers.Contains(entity))
                        ele.collidingPlayers.Remove(entity);
                }
            }
        }
        void NewElevator(ElevatorInfo info)
        {
            var objects = GameObject.FindObjectsOfType(typeof(Elevator));
            if (objects != null)
                foreach (Elevator gameObj in objects)
                {
                    if(gameObj.info.Name == info.Name)
                    {
                        GameObject.Destroy(gameObj);
                    }
                }
            GameObject gameobject = new UnityEngine.GameObject();
            gameobject.AddComponent<Elevator>();
            gameobject.GetComponent<Elevator>().SetInfo(info);
        }
        void Loaded()
        {
            emptyDamageType = new DamageTypeList();
            serverinput = typeof(BasePlayer).GetField("serverInput", (BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic));
            LoadData();
        } 
        void Unload() 
        {
            var objects = GameObject.FindObjectsOfType(typeof(Elevator));
            if (objects != null)
                foreach (Elevator gameObj in objects)
                {
                    GameObject.Destroy(gameObj);
                } 
            foreach (Elevator ele in spawnedElevators)
            {
                if(ele != null) 
                    GameObject.Destroy(ele.gameObject);
            }                    
        }
        void OnServerInitialized()
        {
            foreach (KeyValuePair<string, ElevatorInfo> pair in elevators)
            {
                NewElevator(pair.Value);
            }
        }
        static BuildingBlock CreateBuildingBlock(string prefabname, Vector3 position, Quaternion rotation, int grade)
        {
            UnityEngine.GameObject prefab = GameManager.server.FindPrefab(prefabname);
            if (prefab == null) return null;
            UnityEngine.GameObject build = UnityEngine.Object.Instantiate(prefab);
            if (build == null) return null;
            BuildingBlock block = build.GetComponent<BuildingBlock>();
            if (block == null) return null;
            block.transform.position = position;
            block.transform.rotation = rotation;
            block.gameObject.SetActive(true);
            block.blockDefinition = PrefabAttribute.server.Find<Construction>(block.prefabID);
            block.Spawn(true); 
            block.SetGrade(NumToGrade(grade));
            block.health = block.MaxHealth();
            block.SendNetworkUpdate(BasePlayer.NetworkQueue.Update);
            return block;
        }
        void OnEntityTakeDamage(BaseCombatEntity entity, HitInfo info)
        {
            if(protectedBlock.Contains(entity))
            {
                CancelDamage(info);
            }
        }
        void CancelDamage(HitInfo hitinfo)
        {
            hitinfo.damageTypes = emptyDamageType;
            hitinfo.DoHitEffects = false;
            hitinfo.HitMaterial = 0;
        }
        bool hasPermission(BasePlayer player)
        {
            if (player.net.connection.authLevel > 1) return true;
            return false;
        }
        static bool TryGetPlayerView(BasePlayer player, out Quaternion viewAngle)
        {
            viewAngle = new Quaternion(0f, 0f, 0f, 0f);
            var input = serverinput.GetValue(player) as InputState;
            if (input == null)
                return false;
            if (input.current == null)
                return false;

            viewAngle = Quaternion.Euler(input.current.aimAngles);
            return true;
        }
        /////////////////////////////////////////////////////
        ///  TryGetClosestRayPoint(Vector3 sourcePos, Quaternion sourceDir, out object closestEnt, out Vector3 closestHitpoint)
        ///  Get the closest entity that the player is looking at
        /////////////////////////////////////////////////////
        bool TryGetClosestRayPoint(Vector3 sourcePos, Quaternion sourceDir, out object closestEnt, out Vector3 closestHitpoint)
        {
            Vector3 sourceEye = sourcePos + new Vector3(0f, 1.5f, 0f);
            UnityEngine.Ray ray = new UnityEngine.Ray(sourceEye, sourceDir * Vector3.forward);

            var hits = UnityEngine.Physics.RaycastAll(ray);
            float closestdist = 999999f;
            closestHitpoint = sourcePos;
            closestEnt = false;
            foreach (var hit in hits)
            {
                if (hit.collider.GetComponentInParent<TriggerBase>() == null)
                {
                    if (hit.distance < closestdist)
                    {
                        closestdist = hit.distance;
                        closestEnt = hit.collider;
                        closestHitpoint = hit.point;
                    }
                }
            }
            if (closestEnt is bool)
                return false;
            return true;
        }
        [ChatCommand("elevator_add")]
        void cmdChatElevatorAdd(BasePlayer player, string command, string[] args)
        {
            if (!hasPermission(player)) { SendReply(player, "You don't have access to this command"); return; }
            if (args.Length < 2)
            { 
                SendReply(player, "/elevator_add NAME WAYPOINTS");
                return;
            } 
            var waypoints = Waypoints.Call("GetWaypointsList", args[1]);
            if(waypoints == null)
            {
                SendReply(player, "No waypoints with this name exist");
                return;
            }
            if( ((List<object>)waypoints).Count < 2)
            {
                SendReply(player, "To create an elevator you need at least 2 waypoints");
                return;
            }
            if (!TryGetPlayerView(player, out currentRot)) return;
            if (!TryGetClosestRayPoint(player.transform.position, currentRot, out closestEnt, out closestHitpoint)) return;
            Debug.Log(closestEnt.ToString());
            BuildingBlock block = ((Collider)closestEnt).GetComponentInParent<BuildingBlock>();
            if (block == null) 
            {
                SendReply(player, "What you are looking at is not a building block");
                return;
            }
            var newelevatorinfo = new ElevatorInfo(block, args[0], args[1]);
            if (elevators[newelevatorinfo.Name] != null) storedData.Elevators.Remove(elevators[newelevatorinfo.Name]);
            elevators[newelevatorinfo.Name] = newelevatorinfo;
            storedData.Elevators.Add(elevators[newelevatorinfo.Name]);
            SaveData(); 
            SendReply(player, "You've successfully created a new elevator");
            NewElevator(elevators[newelevatorinfo.Name]);
        }

        [ChatCommand("elevator_reset")]
        void cmdChatElevatorReset(BasePlayer player, string command, string[] args)
        {
            if (!hasPermission(player)) { SendReply(player, "You don't have access to this command"); return; }
            foreach (KeyValuePair<string, ElevatorInfo> pair in elevators)
            {
                storedData.Elevators.Remove(elevators[pair.Key]);
            }
            elevators.Clear();
            SaveData();
            spawnedElevators.Clear();
            SendReply(player, "All elevators were removed");
            Unload();
        }

        [ChatCommand("elevator_remove")]
        void cmdChatElevatorRemove(BasePlayer player, string command, string[] args)
        {
            if (!hasPermission(player)) { SendReply(player, "You don't have access to this command"); return; }
            if(args.Length == 0)
            {
                SendReply(player, "/elevator_remove NAME"); return;
            }
            if(elevators[args[0]] == null)
            {
                SendReply(player, "This elevator doesn't exist"); return;
            }
            foreach (Elevator ele in spawnedElevators)
            {
                if (ele.info.Name == elevators[args[0]].Name)
                    GameObject.Destroy(ele.gameObject);
            }
            storedData.Elevators.Remove(elevators[args[0]]);
            elevators[args[0]] = null;
            SendReply(player, string.Format("Elevator named {0} was deleted",args[0]));
            SaveData();
        }

        [ChatCommand("elevator_list")]
        void cmdChatElevatorList(BasePlayer player, string command, string[] args)
        {
            if (!hasPermission(player)) { SendReply(player, "You don't have access to this command"); return; }
            if(elevators.Count == 0)
            {
                SendReply(player, "You don't have any elevators");
                return;
            }
            foreach (KeyValuePair<string, ElevatorInfo> pair in elevators)
            {
                SendReply(player, string.Format("{0} - {1}", pair.Key, pair.Value.PrefabName));
            }

        }
    }
}

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