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

FREE PersonalVaultDoor : 1.0.2 1.0.2

Нет прав для скачивания
C#:
using Oxide.Game.Rust.Cui;
using ProtoBuf;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
namespace Oxide.Plugins {
    [Info("Personal Vault Door", "bmgjet", "1.0.2")]
    [Description("Lets you place a vault door")]
    public class PersonalVaultDoor : RustPlugin {
#region Vars
        //Starting Health of vault door
        public static float VaultMaxHealth = 2000;
        //Sec delay between taking damage and being able to fix
        public float RepairDelay = 60;
        //Repair per hammer hit
        public int RepairAmmount = 25;
        //Items and quanity needed per repair hit
        public Dictionary<string, int> RepairCost = new Dictionary<string, int> {
            {
                "scrap", 1
            }
            , {
                "metal.fragments", 100
            }
            , {
                "metal.refined", 10
            }
            ,
        }
        ;
        public bool craftcosts = false;
        public Dictionary<string, int> CraftCost = new Dictionary<string, int> {
            {
                "scrap", 10
            }
            , {
                "metal.fragments", 1000
            }
            , {
                "metal.refined", 100
            }
            ,
        }
        ;
        //Offset from door slot position to move lock.
        Vector3 codeoffset = new Vector3(0.71f, -0.1f, -0.3f);
        //Puts it on flat pannel, On handles was too far for it to trigger on door still.
        //Skin of Icon
        private const ulong skinID = 2643584466;
        //Replacement prefab
        private const string prefab = "assets/bundled/prefabs/modding/asset_store/bankheist_package/bankheist_vol03/prefabs/door.vault.static.prefab";
        //Permission
        private const string permUse = "PersonalVaultDoor.use";
        //Show Debug Info
        private bool showDebug = false;
        //Sound Effects to play on vault break.
        static List<string> effects = new List<string> {
            "assets/bundled/prefabs/fx/entities/loot_barrel/gib.prefab", "assets/bundled/prefabs/fx/building/metal_sheet_gib.prefab"
        }
        ;
        private List<Vector3> REPlaced = new List<Vector3>();
        private static PersonalVaultDoor plugin;
#endregion
#region Language
        protected override void LoadDefaultMessages() {
            lang.RegisterMessages(new Dictionary<string, string> {
                {
                    "Name", "Vault Door"
                }
                , {
                    "Pickup", "You picked up Vault Door!"
                }
                , {
                    "Receive", "You received Vault Door!"
                }
                , {
                    "Repair", "You need more resources:\n{0}"
                }
                , {
                    "Wait", "You must wait: {0} before you can repair."
                }
                , {
                    "Permission", "You need permission to do that!"
                }
            }
            , this);
        }
        //Send player message
        private void message(BasePlayer player, string key, params object[] args) {
            if (player == null) {
                return;
            }
            var message = string.Format(lang.GetMessage(key, this, player.UserIDString), args);
            player.ChatMessage(message);
        }
#endregion
#region Oxide Hooks
        private void OnServerInitialized(bool initial) {
            plugin = this;
            //Readd Component
            if (initial) {
                if (showDebug) Puts("First Start Detected");
                Fstartup();
            }
            else {
                CheckVaultDoor();
                ;
            }
        }
        private void Fstartup() {
            //Wait until a player has connected before starting up vault door componant for slow servers.
            timer.Once(10f, () => {
                if (Rust.Application.isLoading) {
                    Fstartup();
                    return;
                }
                covalence.Server.Command("o.reload", this.Name);
            }
            );
        }
        private void Init() {
            //Setup Permissions
            permission.RegisterPermission(permUse, this);
        }
        private void Unload() {
            //Clear Vault Door Health CUI
            foreach (BasePlayer player in BasePlayer.activePlayerList.ToArray()) {
                CuiHelper.DestroyUi(player, "VaultHealth");
            }
            int VDS = DestroyVaultDoorScript();
            if (showDebug) Puts("Destroyed " + VDS.ToString() + " VaultDoor Scripts");
            //Unload Statics
            effects = null;
            plugin = null;
        }
        void OnEntityKill(BaseNetworkable entity) {
            if (entity == null) return;
            //Check if vault door
            if (entity.ShortPrefabName == "door.vault.static") {
                VaultDoor VD = entity.GetComponent<VaultDoor>();
                if (VD == null) return;
                //Remove Door Frame
                NextTick(() => {
                    if (VD.Frame != null) {
                        VD.Frame.Kill();
                    }
                }
                );
                if (VD.PlayersCUIed == null) return;
                //Remove CUI
                foreach (BasePlayer player in VD.PlayersCUIed) {
                    if (player != null) {
                        CuiHelper.DestroyUi(player, "VaultHealth");
                    }
                }
                UnityEngine.Object.DestroyImmediate(VD);
            }
        }
        //Code and KeyLock position Fix
        void OnEntitySpawned(BaseEntity cl) {
            if (Rust.Application.isLoading) return;
            if (cl == null) {
                return;
            }
            //Checks if codelock/keylock
            if (cl is CodeLock || cl is KeyLock) {
                //Checks if its a vault door
                BaseEntity Door = cl.GetParentEntity();
                if (Door != null && Door.ToString().Contains("door.vault.static")) {
                    //Moves codelock and update
                    cl.transform.localPosition += codeoffset;
                    cl.SendNetworkUpdateImmediate(true);
                }
            }
            //Add component in spawn here so Copypaste can Work with vaultdoors.
            if (cl is Door && cl.ToString().Contains("door.vault.static")) {
                if (cl.GetComponent<VaultDoor>() == null) {
                    if (REPlaced.Contains(cl.transform.position)) {
                        if (showDebug) Puts("Skipping Rust Edit Placed Vault Door");
                        return;
                    }
                    if (showDebug) Puts("Adding VaultDoor Component");
                    //Delay since copypaste might not of spawn door frame yet.
                    timer.Once(2f, () => {
                        try {
                            cl.gameObject.AddComponent<VaultDoor>();
                        }
                        catch {
                        }
                        ;
                    }
                    );
                }
            }
        }
        //Hook vault placement to switch in.
        private void OnEntityBuilt(Planner plan, GameObject go) {
            CheckDeploy(go.ToBaseEntity());
        }
        //Hooks if should pickup
        private void OnHammerHit(BasePlayer player, HitInfo info) {
            CheckHit(player, info?.HitEntity);
        }
#endregion
#region Core
        List<Door> FindVaultDoors(Vector3 pos, float radius) {
            //Casts a sphere at given position and find all doors there
            var hits = Physics.SphereCastAll(pos, radius, Vector3.one);
            var x = new List<Door>();
            foreach (var hit in hits) {
                var entity = hit.GetEntity()?.GetComponent<Door>();
                if (entity && !x.Contains(entity)) x.Add(entity);
            }
            return x;
        }
        void DestroyGroundComp(BaseEntity ent) {
            UnityEngine.Object.DestroyImmediate(ent.GetComponent<DestroyOnGroundMissing>());
            UnityEngine.Object.DestroyImmediate(ent.GetComponent<GroundWatch>());
            //Stops Decay
            UnityEngine.Object.DestroyImmediate(ent.GetComponent<DeployableDecay>());
        }
        void DestroyMeshCollider(BaseEntity ent) {
            foreach (var mesh in ent.GetComponentsInChildren<MeshCollider>()) {
                UnityEngine.Object.DestroyImmediate(mesh);
            }
        }
        //Resets the component after server restart
        private void CheckVaultDoor() {
            //Build list of VaultDoors In Map File
            for (int i = World.Serialization.world.prefabs.Count - 1; i >= 0; i--) {
                PrefabData prefabdata = World.Serialization.world.prefabs[i];
                if (prefabdata.id == 3595032872) {
                    REPlaced.Add(prefabdata.position);
                    //Check its still there and fix if not
                    if (FindVaultDoors(prefabdata.position, 4f).Count == 0) {
                        Door replacement = GameManager.server.CreateEntity(StringPool.Get(prefabdata.id), prefabdata.position, prefabdata.rotation) as Door;
                        if (replacement == null) return;
                        DestroyGroundComp(replacement);
                        DestroyMeshCollider(replacement);
                        replacement.Spawn();
                        replacement.transform.position = prefabdata.position;
                        replacement.transform.rotation = prefabdata.rotation;
                        replacement.pickup.enabled = false;
                        replacement.SendNetworkUpdateImmediate(true);
                    }
                }
            }
            if (showDebug) Puts("Founded " + REPlaced.Count.ToString() + " Map Placed Vault Doors");
            int VaultsUpdated = 0;
            foreach (var vaultdoor in GameObject.FindObjectsOfType<BaseEntity>()) {
                //Skip Servers Vault Doors
                if (REPlaced.Contains(vaultdoor.transform.position)) {
                    if (showDebug) Puts("Skipping Map Placed Vault Door @ " + vaultdoor.transform.position.ToString());
                    continue;
                }
                if (vaultdoor.ShortPrefabName == "door.vault.static" && vaultdoor.GetComponent<VaultDoor>() == null) {
                    if (showDebug) Puts("Found vaultdoor " + vaultdoor.ToString() + " " + vaultdoor.OwnerID.ToString() + " Adding Component");
                    vaultdoor.gameObject.AddComponent<VaultDoor>();
                    VaultsUpdated++;
                }
            }
            Puts("Updated " + VaultsUpdated.ToString() + " VaultDoors");
        }
        //Gives player vault door
        private void GiveVaultDoor(BasePlayer player, bool pickup = false) {
            var item = CreateItem();
            if (item != null && player != null) {
                player.GiveItem(item);
                message(player, pickup ? "Pickup" : "Receive");
            }
        }
        //Checks if has the correct permission
        private bool CanCraft(BasePlayer player) {
            if (!permission.UserHasPermission(player.UserIDString, permUse)) {
                message(player, "Permission");
                return false;
            }
            return CanFix(player, null, true);
        }
        //Creates vault door
        private Item CreateItem() {
            var item = ItemManager.CreateByName("wall.frame.garagedoor", 1, skinID);
            if (item != null) {
                item.text = "Vault Door";
                item.name = item.text;
            }
            return item;
        }
        //Checks if its a vault door when hit with hammer
        private void CheckHit(BasePlayer player, BaseEntity entity) {
            if (entity == null) {
                return;
            }
            if (!IsVaultDoor(entity.skinID)) {
                return;
            }
            //Check if door is open and has no lock to remove Otherwise heal door
            Door VD = entity as Door;
            if (VD.GetSlot(0) == null && VD.IsOpen()) {
                entity.GetComponent<VaultDoor>()?.TryPickup(player);
            }
            else {
                if (VD._health < VD._maxHealth && CanFix(player, VD)) {
                    Effect.server.Run("assets/bundled/prefabs/fx/build/repair_full_metal.prefab", VD.transform.position);
                    VD.health += RepairAmmount;
                }
            }
        }
        //Checks if can fix
        private bool CanFix(BasePlayer player, Door VD, bool craft = false) {
            Dictionary<string, int> Needed = new Dictionary<string, int>();
            Dictionary<string, int> Parts = new Dictionary<string, int>();
            if (!craft) {
                Parts = RepairCost;
                //Check repair delay
                if (VD.SecondsSinceAttacked < RepairDelay) {
                    message(player, "Wait", (RepairDelay - VD.SecondsSinceAttacked).ToString("#.#"));
                    return false;
                }
            }
            else {
                if (!craftcosts) return true;
                Parts = CraftCost;
            }
            //Check has needed meterials
            foreach (var component in Parts) {
                string name = component.Key;
                if (player.inventory.GetAmount(ItemManager.FindItemDefinition(component.Key).itemid) < component.Value) {
                    if (!Needed.ContainsKey(name)) {
                        Needed.Add(name, 0);
                    }
                    Needed[name] += component.Value;
                }
            }
            //Has everything needed so remove from player and send can fix.
            if (Needed.Count == 0) {
                foreach (var item in Parts) {
                    player.inventory.Take(null, ItemManager.FindItemDefinition(item.Key).itemid, item.Value);
                }
                return true;
            }
            //Doesnt have everything needed to build list and message use. Send cant fix
            else {
                string text = "";
                foreach (var item in Needed) {
                    text += $" * {item.Key} x{item.Value}\n";
                }
                message(player, "Repair", text);
                return false;
            }
        }
        private bool IsVaultDoor(ulong skin) {
            return skin != 0 && skin == skinID;
        }
        //Checks if vault door should be swapped in
        private void CheckDeploy(BaseEntity entity) {
            if (entity == null) {
                return;
            }
            //Checks if is using vault door skin
            if (!IsVaultDoor(entity.skinID)) {
                return;
            }
            //Creates Doorway
            var doorway = GameManager.server.CreateEntity("assets/prefabs/building core/wall.doorway/wall.doorway.prefab", entity.transform.position, entity.transform.rotation);
            if (doorway == null) {
                //Something Failed
                return;
            }
            doorway.Spawn();
            doorway.OwnerID = entity.OwnerID;
            //sets up door frame to fill in gaps around vault door
            var buildingBlock = doorway as BuildingBlock;
            if (buildingBlock != null) {
                //Upgrade HQM
                buildingBlock.SetGrade((BuildingGrade.Enum)4);
                //Grounded so doesnt fall apart
                buildingBlock.grounded = false;
                //Sets health as max
                buildingBlock.health = buildingBlock.MaxHealth();
                //Rotate from Door Way
                Vector3 rot = buildingBlock.transform.rotation.eulerAngles;
                rot = new Vector3(rot.x, rot.y + 180, rot.z);
                //Create Vault Door
                Door vaultdoor = GameManager.server.CreateEntity(prefab, buildingBlock.transform.position, buildingBlock.transform.rotation) as Door;
                if (vaultdoor == null) {
                    return;
                }
                //Stupid rotation based move stuff
                Vector3 movepos = buildingBlock.transform.position;
                movepos += buildingBlock.transform.forward * 1.0f;
                movepos += buildingBlock.transform.right * -0.54f;
                movepos += buildingBlock.transform.up * 0.2f;
                //Sets door way as creator so can destory vault on door way being destroyed
                vaultdoor.creatorEntity = doorway;
                vaultdoor.transform.rotation = Quaternion.Euler(rot);
                vaultdoor.transform.position = movepos;
                //Set skin and owner
                vaultdoor.skinID = skinID;
                vaultdoor.OwnerID = entity.OwnerID;
                //Delay setting Max health and health other wise it defaults to 800
                timer.Once(1f, () => {
                    vaultdoor.SetMaxHealth(VaultMaxHealth);
                    vaultdoor.SetHealth(VaultMaxHealth);
                }
                );
                //Sets up functions
                vaultdoor.Spawn();
                vaultdoor.SendNetworkUpdateImmediate();
            }
            //Cleans out placeholder
            NextTick(() => {
                entity?.Kill();
            }
            );
        }
        //Removes script on unload incase some ones restarting plugin but not restarted server
        int DestroyVaultDoorScript() {
            int killed = 0;
            foreach (var vaultdoor in GameObject.FindObjectsOfType<Door>()) {
                foreach (var vd in vaultdoor.GetComponentsInChildren<VaultDoor>()) {
                    UnityEngine.Object.DestroyImmediate(vd);
                    killed++;
                }
            }
            return killed;
        }
#endregion
#region Commands
        //Chat command
        [ChatCommand("vaultdoor.craft")]
        private void Craft(BasePlayer player) {
            if (CanCraft(player)) {
                GiveVaultDoor(player);
            }
        }
        //Console command
        [ConsoleCommand("vaultdoor.give")]
        private void Cmd(ConsoleSystem.Arg arg) {
            if (arg.IsAdmin && arg.Args?.Length > 0) {
                var player = BasePlayer.Find(arg.Args[0]) ?? BasePlayer.FindSleeping(arg.Args[0]);
                if (player == null) {
                    PrintWarning($"Can't find player with that name/ID! {arg.Args[0]}");
                    return;
                }
                GiveVaultDoor(player);
            }
        }
#endregion
#region Scripts
        public class VaultDoor : MonoBehaviour {
            //Hold doors info
            public Door vdoor = null;
            //Holds Position that can be used after Vdoors destroyed.
            public Vector3 Position;
            //Hold door frames info
            public BaseEntity Frame = null;
            //List of players that have CUI active
            public List<BasePlayer> PlayersCUIed = new List<BasePlayer>();
            private void Awake() {
                //Setup
                vdoor = this.GetComponent<Door>();
                if (vdoor == null) return;
                Position = vdoor.transform.position;
                //Set Custom Health
                vdoor.SetMaxHealth(VaultMaxHealth);
                vdoor.SetHealth(VaultMaxHealth);
                Frame = vdoor.creatorEntity;
                //If no creatorEntity most likey a server restart so find it.
                if (Frame == null) {
                    //Offsets scan position since where vault shows isnt where its position is.
                    Vector3 scanpos = Position;
                    scanpos += vdoor.transform.forward * 1.0f;
                    scanpos += vdoor.transform.right * -0.54f;
                    scanpos += vdoor.transform.up * 0.0f;
                    if (plugin.showDebug) foreach (BasePlayer BP in BasePlayer.activePlayerList) {
                        if (BP.IsAdmin) BP.SendConsoleCommand("ddraw.sphere", 8f, Color.red, scanpos, 0.5f);
                    }
                    List<BaseEntity> BuildingBlock = new List<BaseEntity>();
                    //Scans area for players
                    Vis.Entities<BaseEntity>(scanpos, 0.5f, BuildingBlock);
                    foreach (BaseEntity doorframe in BuildingBlock) {
                        if (doorframe.ShortPrefabName == "wall.doorway") {
                            if (plugin.showDebug) plugin.Puts("Found Creator Doorway " + doorframe.ToString());
                            Frame = doorframe;
                            break;
                        }
                    }
                }
                //Setup checking if door frame has been destroyed
                InvokeRepeating("CheckFrame", 5, 8);
                InvokeRepeating("VaultHealthBar", 2, 2);
            }
            void VaultHealthBar() {
                List<BasePlayer> PlayersInRange = new List<BasePlayer>();
                //Scans area for players
                Vis.Entities<BasePlayer>(vdoor.transform.position, 5f, PlayersInRange);
                //Logic to remove CUI from players that have left area
                foreach (BasePlayer bp in PlayersCUIed.ToArray()) {
                    if (!PlayersInRange.Contains(bp)) {
                        CuiHelper.DestroyUi(bp, "VaultHealth");
                        PlayersCUIed.Remove(bp);
                    }
                }
                //Shows CUI to each player in range
                if (PlayersInRange.Count != 0) {
                    foreach (BasePlayer player in PlayersInRange.ToArray()) {
                        if (!player.IsSleeping()) {
                            CuiHelper.DestroyUi(player, "VaultHealth");
                            var elements = new CuiElementContainer();
                            elements.Add(new CuiLabel {
                                Text = {
                                    Text = "Vault Health " + vdoor._health.ToString("#.##") + "/" + vdoor._maxHealth.ToString(), FontSize = 16, Align = TextAnchor.MiddleCenter
                                }
                                , RectTransform = {
                                    AnchorMin = "0.806 0.955", AnchorMax = "0.99 0.989"
                                }
                            }
                            , "Overlay", "VaultHealth");
                            CuiHelper.AddUi(player, elements);
                            if (!PlayersCUIed.Contains(player)) {
                                PlayersCUIed.Add(player);
                            }
                        }
                    }
                }
            }
            void CheckFrame() {
                //Frame has been destoryed so destroy vault
                try {
                    if (Frame == null && vdoor != null) {
                        foreach (var effect in effects) {
                            Effect.server.Run(effect, Position);
                        }
                        vdoor.Kill();
                    }
                }
                catch {
                }
            }
            public void TryPickup(BasePlayer player) {
                //Owner has hit with hammer, Destroy frame and vault door and refund them one.
                if (vdoor.OwnerID == player.userID) {
                    vdoor.Kill();
                    if (Frame != null) {
                        Frame.Kill();
                    }
                    plugin.GiveVaultDoor(player, true);
                }
            }
        }
#endregion
    }
}

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